进程(二)

来源:互联网 发布:mysql use index用法 编辑:程序博客网 时间:2024/06/04 18:54

1.fork()

fork创建一个新进程。这个系统调用复制当前进程,在进程表中创建一个新的表项,新进程几乎与原进程一模一样,执行的代码也是完全一样,但新进程有自己的数据空间、环境、文件描述符。

#include<sys/types.h>#include<unistd.h>pid_t fork(void);
返回值:
  • 如果成功创建一个子进程,对于父进程来说返回子进程ID
  • 如果成功创建一个子进程,对于子进程来说返回值为0
  • 如果为-1表示创建失败

  1. 使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。
  2. 子进程与父进程的区别在于:

    • 1、父进程设置的锁,子进程不继承
    • 2、各自的进程ID和父进程ID不同
    • 3、子进程的未决告警被清除;
    • 4、子进程的未决信号集设置为空集。
     3. fork系统调用需要注意的地方

    • fork系统调用之后,父子进程将交替执行。
    • 如果父进程先退出,子进程还没退出那么子进程的父进程将变为init进程。(注:任何一个进程都必须有父进程)
    • 如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵进程。
    • 子进程退出会发送SIGCHLD信号给父进程,可以选择忽略或使用信号处理函数接收处理就可以避免僵尸进程。
一个fork的例子
/*fork.c*/#include<stdio.h>#include<unistd.h>#include<sys/types.h>int main(){    pid_t pid;    char *message;    pid=fork();    if(pid<0)    {perror("fork error!");exit(1);    }    else if(pid>0)    {message="this is parent!";printf("%s ppid=%d\n",message,pid);    }    else    {message="this is child!";printf("%s ppid=%d\n",message,pid);    }    return 0;}


make fork./fork1
结果是:
this is parent! ppid=2486zhou@hyn-virtual-machine:~/os/test/test1/daemon$ this is child! ppid=0
委屈结果是乱的,别急我们来看第二个函数;

2.wait()

在例程fork1.c中由于父进程先于子进程结束;所以输出结果有点乱,我们可以在父进程中调用wait()等待子进程结束;

#include<sys/types.h>#include<sys/wait.h>pid_t wait(int *stat_loc);

wait()会暂时停止进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束状态值会由参数status 返回,而子进程的进程识别码也会一起返回。如果不在意结束状态值,则参数status 可以设成NULL。

结束状态值信息:

  • WIFEXITED(stat_val)如果子进程正常结束,他就取一个非零值
  • WEXITSTATUS(stat_val)如果WIFEXITED非零,他返回子进程的退出码
  • WIFSIGNALED(stat_val)如果子进程因为一个未捕获的信号而终止,他就取一个非零值
  • WTERMSIG(stat_val)如果WIFSIGNALED非零,他返回一个信号代码
  • WIFSTOPPED(stat_val)如果子进程意外终止,它就取一个非零值
  • WSTOPSIG(stat_val)如果WIFSTOPPED非零,他返回一个信号代码

一个wait的例子

/*wait.c*/#include<stdio.h>#include<unistd.h>#include<sys/types.h>#include<sys/wait.h>int main(){    pid_t pid;    char *message;    pid=fork();    int exit_code;    if(pid<0)    {perror("fork error!");exit(1);    }    else if(pid>0)    {message="this is parent!";printf("%s ppid=%d\n",message,pid);int stat_val;pid_t child_pid;child_pid=wait(&stat_val);if(WIFEXITED(stat_val)){printf("child exited with code%d\n",WEXITSTATUS(stat_val));}else{printf("child terminated abnormally\n");}    }    else    {message="this is child!";printf("%s ppid=%d\n",message,pid);exit_code=37;    }    exit(exit_code);}

make wait./wait

结果是
this is parent! ppid=2576this is child! ppid=0child exited with code37
原创粉丝点击