目录
父子进程间的同步 - wait
子进程运行新程序 - exec
1. wait和waitpid函数
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
int fd, pid, status;
char buf[10];
if ((fd = open("/tmp/yangzhu.txt", O_RDONLY)) < 0) {
perror("open");
exit(-1);
}
if ((pid = fork()) < 0) {
perror("fork");
exit(-1);
} else if (pid == 0) {
sleep(5); //子进程睡眠5秒
read(fd, buf, 2);
write(STDOUT_FILENO, buf, 2);
} else {
wait(&status); //等待子程序结束后再运行(status:子程序的结束状态)
lseek(fd, SEEK_CUR, 1);
read(fd, buf, 3);
write(STDOUT_FILENO, buf, 3);
write(STDOUT_FILENO, "\n", 1);
}
return 0;
}
运行结果:子程序睡眠5秒后运行打印 ab ,主进程等待子程序运行结束后再打印 def ,最终屏幕显示 abdef 。
2. exec函数
典型例子:shell终端窗口,输入ls命令,将运行 ls 子进程,那么ls子进程运行的程序与shell主进程运行的程序完全无关。
pathname:是新程序的全路径名
arg0:是新程序名称,即argv[0]
...:命令行参数,即如argv[1]、argv[2]...
/* (char *)0 */:最后一个参数填写 0 ,代表命令行参数没有了
envp[]:指定新进程的环境变量,不是默认父进程的环境变量
filename:要么是新程序的绝对路径;要么是全路径名;要么是新程序文件名,自动加上环境变量PATH路径名查找新程序全路径名
//echoall.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int i;
char **ptr;
extern char **environ;
for (i = 0; i < argc; i++)
printf("argv[%d]: %s\n", i, argv[i]);
for (ptr = environ; *ptr != 0; ptr++)
printf("%s\n", *ptr);
exit(0);
}
//exec.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
char *env_init[] = { "USER=unkown", "PATH=/tmp", NULL };
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0)
perror("fork error");
else if (pid == 0) {
if (execle("./echoall", "echoall", "myarg1", "MY ARG2", (char *) 0, env_init) < 0)
perror("execle error");
}
if ((pid = fork()) < 0)
perror("fork error");
else if (pid == 0) {
if (execlp("./echoall", "echoall", "only 1 arg", (char *) 0) < 0)
perror("execlp error");
}
exit(0);
}