案例6-1:使用fork()函数创建一个进程,进程创建成功后使父进程与子进程分别执行不同的功能。
test_fork.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = fork(); //调用fork()函数创建子进程
if (pid == -1) //创建失败
{
perror("fork error");
exit(1); //退出进程,指定返回值1
}
else if (pid > 0) //父进程
{
printf("parent process,pid=%d,ppid=%d\n", getpid(), getppid());
}
else if (pid == 0) //子进程
{
printf("child process,pid=%d,ppid=%d\n", getpid(), getppid());
}
printf("........finish..........\n");
return 0;
}
案例6-2:删除打印finish的printf()。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
pid_t pid;
int i;
for (i = 0; i<5; i++){ //循环创建进程
if ((pid = fork()) == 0) //若当前进程为子进程,便跳出循环
break;
}
if (pid == -1){
perror("fork error");
exit(1);
}
else if (pid>0){ //父进程
printf("parent process:pid=%d\n", getpid());
}
else if (pid == 0){ //子进程
printf("I am child=%d,pid=%d\n", i + 1, getpid());
}
return 0;
}
案例6-3:在程序中创建一个子进程,之后使父进程打印自己的pid信息,使子进程通过exec函数族获取系统命令文件,执行ls命令。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = fork();
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
printf("parent process:pid=%d\n", getpid());
}
else if (pid == 0)
{
printf("child process:pid=%d\n", getpid());
//execl("/bin/ls","-a","-l","test_fork.c",NULL); //①
//execlp("ls","-a","-l","test_fork.c",NULL); //②
char *arg[] = { "-a", "-l", "test_fork.c", NULL }; //③
execvp("ls", arg);
perror("error exec\n");
printf("child process:pid=%d\n", getpid());
}
return 0;
}
案例6-4:若子进程pl是其父进程p的先决进程,使用wait()函数使进程同步。
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
int main()
{
pid_t pid, w;
pid = fork();
if (pid == -1){
perror("fork error");
exit(1);
}
else if (pid == 0){
sleep(3);
printf("Child process:pid=%d\n", getpid());
}
else if (pid > 0){
w = wait(NULL);
printf("Catched a child process,pid=%d\n", w);
}
return 0;
}
案例6-5:使用wait()函数同步进程,并使用宏获取子进程的返回值。
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
int main()
{
int status;
pid_t pid, w;
pid = fork();
if (pid == -1){
perror("fork error");
exit(1);
}
else if (pid == 0){
sleep(3);
printf("Child process:pid=%d\n", getpid());
exit(5);
}
else if (pid > 0){
w = wait(&status);
if (WIFEXITED(status)){
printf("Child process pid=%d exit normally.\n", w);
printf("Return Code:%d\n", WEXITSTATUS(status));
}
else
printf("Child process pid=%d exit abnormally.\n", w);
}
return 0;
}
案例6-6:使父进程等待进程组中某个指定的进程,若该进程不退出,则让父进程一直阻塞。
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
pid_t pid, p, w;
pid = fork(); //创建第一个子进程
if (pid == -1){ //第一个子进程创建后父子进程的执行内容
perror("fork1 error");
exit(1);
}
else if (pid == 0){ //子进程沉睡
sleep(5);
printf("First child process:pid=%d\n", getpid());
}
else if (pid > 0){ //父进程继续创建进程
int i;
p = pid;
for (i = 0; i < 3; i++) //由父进程创建3个子进程
{
if ((pid = fork()) == 0)
break;
}
if (pid == -1){ //出错
perror("fork error");
exit(2);
}
else if (pid == 0){ //子进程
printf("Child process:pid=%d\n", getpid());
exit(0);
}
else if (pid > 0){ //父进程
w = waitpid(p, NULL, 0); //等待第一个子进程执行
if (w == p)
printf("Catch a child Process:pid=%d\n", w);
else
printf("waitpid error\n");
}
}
return 0;
}
案例6-7:使用waitpid()函数不断获取某进程中子进程的状态。
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
pid_t pid, w;
pid = fork();
if (pid == -1){
perror("fork error");
exit(1);
}
else if (pid == 0){
sleep(3);
printf("Child process:pid=%d\n", getpid());
exit(0);
}
else if (pid > 0){
do{
w = waitpid(pid, NULL, WNOHANG);
if (w == 0){
printf("No child exited\n");
sleep(1);
}
} while (w == 0);
if (w == pid)
printf("Catch a Child process:pid=%d\n", w);
else
printf("waitpid error\n");
}
return 0;
}