到目前为止,我们知道无论何时执行程序,都会创建一个进程,并在执行完成后终止.如果我们需要在程序中创建流程并且可能希望为其安排不同的任务,该怎么办?这可以实现吗?是的,显然是通过创建流程.当然,在完成工作后,它会自动终止,或者您可以根据需要终止它.
通过 fork()系统调用实现流程创建 .新创建的进程称为子进程,启动它的进程(或启动执行时的进程)称为父进程.在fork()系统调用之后,现在我们有两个进程 - 父进程和子进程.如何区分它们?非常简单,它是通过它们的返回值.
创建子进程后,让我们看一下fork()系统调用的详细信息.
#include< sys/types.h> #include< unistd.h> pid_t fork(void);
创建子进程.在此调用之后,有两个进程,现有的一个称为父进程,新创建的一个进程称为子进程.
fork()系统调用返回三个进程中的任何一个值 :
表示错误的负值,即创建子进程失败.
为子进程返回零.
返回父进程的正值.此值是新创建的子进程的进程ID.
让我们考虑一个简单的程序.
File name: basicfork.c #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { fork(); printf("Called fork() system call\n"); return 0; }
gcc basicfork.c -o basicfork
Called fork() system call Called fork() system call
注意 : 号;通常在fork()调用之后,子进程和父进程将执行不同的任务.如果需要运行相同的任务,那么对于每个fork()调用,它将运行2次幂n次,其中 n 是fork()被调用的次数.
在上面的例子中,fork()被调用一次,因此输出被打印两次(2次幂1).如果调用fork(),比如说3次,则输出将被打印8次(2次幂3).如果它被调用了5次,那么它会打印32次,依此类推.
看过fork()后创建子进程,是时候查看父进程的详细信息了和子进程.
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { pid_t pid, mypid, myppid; pid = getpid(); printf("Before fork: Process id is %d\n", pid); pid = fork(); if (pid < 0) { perror("fork() failure\n"); return 1; } // Child process if (pid == 0) { printf("This is child process\n"); mypid = getpid(); myppid = getppid(); printf("Process id is %d and PPID is %d\n", mypid, myppid); } else { // Parent process sleep(2); printf("This is parent process\n"); mypid = getpid(); myppid = getppid(); printf("Process id is %d and PPID is %d\n", mypid, myppid); printf("Newly created process id or child pid is %d\n", pid); } return 0; }
Before fork: Process id is 166629 This is child process Process id is 166630 and PPID is 166629 Before fork: Process id is 166629 This is parent process Process id is 166629 and PPID is 166628 Newly created process id or child pid is 166630
进程可以以两种方式中的任何一种终止 :
在发送某些信号时发生异常,例如终止信号.
通常,使用_exit()系统调用(或_Exit()系统调用)或exit()库函数.
_exit()和exit()之间的区别主要是清理活动. exit()在将控件返回内核之前进行一些清理,而 _exit()(或_Exit())会立即将控件返回给内核.
使用exit()考虑以下示例程序.
#include <stdio.h> #include <stdlib.h> void exitfunc() { printf("Called cleanup function - exitfunc()\n"); return; } int main() { atexit(exitfunc); printf("Hello, World!\n"); exit (0); }
Hello, World! Called cleanup function - exitfunc()
使用_exit()考虑以下示例程序.
#include <stdio.h> #include <unistd.h> void exitfunc() { printf("Called cleanup function - exitfunc()\n"); return; } int main() { atexit(exitfunc); printf("Hello, World!\n"); _exit (0); }
Hello, World!