(1)当执行程序时,main函数是的如何调用的
main函数原型是
- int main(int argc,char *argv[]);
- argc是命令行参数,argv是指向参数的各个指针的数组。
-
- #include"apue.h"
-
- int main()
- {
- int i;
- for(i=0;i<argc;i++)
- {
- printf("argv[%d]:%s\n",i,argv[i]);
- exit(0);
- }
- //编译运行后如下:
- zsj@zsj-virtual-machine:~/ccode$ cc -o 7-3 7-3.c
- zsj@zsj-virtual-machine:~/ccode$ ./7-3 arg1 TEST foo
- argv[0]:./7-3 //第一个指针指向文件
- argv[1]:arg1
- argv[2]:TEST
- argv[3]:foo
内核执行c程序时(使用exec函数)调用main之前先调用一个特殊例程。例程从内核取得命令行参数 和环境变量值。
(2)各种不同的进程终止方式
- #include<stdlib.h>
- void exit(int status);
- void_Exit(int status);
-
- #include<unistd.h>
- void _exit(int status);
这三个函数都可以用来正常终止一个程序:_exit 和_Exit立即进入内核,exit则执行一些清理操作(调用执行各终止处理程序,关闭所有标准I/O流)
@H_301_86@三个函数都带一个整型参数称为终止状态。(a)调用这些函数时不带终止状态.
(b)main执行了一个无返回值的return语句
(c)main没有声明返回值是整型的。
以上三种情况 终止状态是未定义的。
(3)c程序的存储空间布局
text:正文段。这是由cpu执行的机器指令部分,正文段是可共享的,正文段常常是只读的。
初始化数据段。出现在任何函数以外的声明。
非初始化数据段。开始执行程序之前内核将此段中的数据初始化为0或空指针。
栈:自动变量以及每次函数调用时所保存的信息都放在栈中。递归函数每次调用自身都使用一个新的栈帧
堆:通常在堆中进行动态存储分配。
(4)如何分配存储空间
(5)创建进程以及进程属性
进程标识符
@H_301_86@每个进程都有一个非负整数表示的唯一进程ID。进程ID可以重用,当一个进程终止时,进程ID就可以重新使用了。系统中有一些专用的进程 ID为0的表示 调度进程,被称为交换进程。并不执行磁盘上的任何程序。
ID为1的是init进程,它通常读与系统初始化有关的文件。
fork函数
- #include<unistd.h>
- pid_t fork(void)
-
- 返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1
@H_301_86@由fork创建的新进程称为子进程。fork函数被调用一次,但返回两次。 父进程返回新进程ID,新进程返回0。 @H_301_86@子进程和父进程继续执行fork()之后的指令。子进程是父进程的副本。获得父进程的数据空间、堆栈、父子进程并不共享这些存储部分。父子进程共享正文段。
- #include<stdio.h>
- #include"apue.h"
- #include<myerror.h>
-
-
- int glob=6;
- char buf[]="a write to stdout\n";
- int main(void)
- {
- int var;
- pid_t pid;
-
- var=88;
-
- if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1)
- err_sys("write error");
- printf("before fork\n");
- if(pid=fork()<0)
- {
- err_sys("fork error");
-
- }
-
- else if(pid==0)
- {
- glob++;
- var++;
- }
- else{
-
- sleep(2);
-
- }
-
- printf("pid= %d,glob=%d,var=%d\n",getpid(),glob,var);
-
- exit(0);
-
-
- }
-
- zsj@zsj-virtual-machine:~/ccode$ cc 8-1.c
- zsj@zsj-virtual-machine:~/ccode$ ./a.out
- a write to stdout
- before fork
- pid=14828,glob=7,var=89 //子进程的变量变了
- pid=14827,glob=6,var=88 //父进程得变量值没变
- zsj@zsj-virtual-machine:~/ccode$ ./a.out >temp.out
- zsj@zsj-virtual-machine:~/ccode$ cat temp.out
- a write to stdout
- before fork
- pid=14830,var=89
- before fork
- pid=14829,var=88
- zsj@zsj-virtual-machine:~/ccode$