前言 大家好吖,欢迎来到 YY 滴Linux系列 ,热烈欢迎! 本章主要内容面向接触过Linux的老铁 主要内容含:
#include <unistd.h>
pid_t fork(void);
返回值:在子进程中返回0
在父进程中返回子进程id,出错返回-1
echo $? ------指令
10 -------结果
#include <errno.h>
-- 测试调用失败情况
FILE *fp = fopen("./log.txt","r");
strerror():
printf("after: %d, error string : %s\n, errno, strerror(errno)");
// 对比下面两个程序,一个带\n,一个不带\n
// \n是行刷新,刷新到显示器上
int main()
{
printf("you can see me!\n");
sleep(6);
exit(1);
}现象:遇到刷新条件,立刻刷新显示you can see me,6s后,程序退出
int main()
{
printf("you can see me!");
sleep(6);
exit(1);
}现象:不立刻显示,6s后程序退出,强制刷新显示
// 对比下面两个程序,一个带\n,一个不带\n
// \n是行刷新,刷新到显示器上
int main()
{
printf("you can see me!\n");
sleep(6);
_exit(1);
}现象:遇到刷新条件,立刻刷新显示you can see me,6s后,程序退出
int main()
{
printf("you can see me!");
sleep(6);
_exit(1);
}现象:不立刻显示,6s后程序退出,也不会刷新显示
kill -l
可以看到有许多信号#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int*status);
演示:
void Worker(int number)
{
int cnt = 5;
while(cnt)
{
printf("I am child process, pid: %d, ppid: %d, cnt: %d, number: %d\n", getpid(), getppid(), cnt--);//蓝色部分
sleep(1);
}
}
int main()
{
pid_t id = fork();
if(id == 0) {//child
Worker();
exit(0);
}
else{//father橙色部分
pid_t rid2 = wait(NULL);//wait函数
if(rid == id)
{
printf("wait success, pid:%d\n",getpid());
}
return 0;
}
返回值:
参数:
pid_ t waitpid(pid_t pid, int *status, int options);
演示:
void Worker(int number)
{
int cnt = 5;
while(cnt)
{
printf("I am child process, pid: %d, ppid: %d, cnt: %d, number: %d\n", getpid(), getppid(), cnt--);
sleep(1);
}
}
int main()
{
pid_t id = fork();
if(id == 0)
{//child
Worker();
exit(0);
}
else{//father
printf("wait before\n");
pid_t rid = waitpid(id,NULL,0);//waitpid函数
printf("wait after\n");
if(rid == id)
{
printf("wait success, pid:%d\n",getpid());
}
return 0;
}
pid_ t waitpid(pid_t pid, int *status, int options);
原理:
status规则:
现象演示:
exit(10);
,通过status把子进程的退出信息返回void Worker(int number)
{
int cnt = 5;
while(cnt)
{
printf("I am child process, pid: %d, ppid: %d, cnt: %d, number: %d\n", getpid(), getppid(), cnt--);
sleep(1);
}
}
int main()
{
pid_t id = fork();
if(id == 0)
{//child
Worker();
exit(10);//设置成10
}
else{//father
printf("wait before\n");
int status =0; //定义一个整型变量 status
pid_t rid = waitpid(id,&status,0);//通过status把子进程的退出信息返回
printf("wait before\n");
if(rid == id)
{
printf("wait success, pid:%d\n",getpid(),status);//打印status指向的区域的内容
}
return 0;
}
2560 //输出结果为2560,而不是10
机制:
演示:
//注:我们只要知道下面execl函数是 起到进程替换的作用就行
//即执行ls -a -l -n 指令,具体使用细节看下文exec类函数模块
int main()
{
pid_t id = fork();
if(id == 0)
{
printf("pid: %d, exec command begin\n",getpid());//语句begin
execl("/usr/bin/ls", "lsaaa", "-a", "-l", "-n", NULL);
printf("pid: %d, exec command end\n", getpid());//语句end
exit(1);
}
else{
// father
pid_t rid = waitpid(-1, NULL, 0);
if(rid > 0)
{
printf("wait success, rid: %d\n", rid);
}
}
return 0;
}
exec类函数有如下几种:都是为了满足各种调用的场景
注意事项:
#include <unistd.h>
int main()
{
//第一个参数找到可执行程序
//后面的参数以列表形式(带l)告诉exec怎么执行
//以NULL结尾
execl("/bin/ps", "ps", "-ef", NULL);
execl("/usr/bin/top", "top", NULL);
execl("/usr/bin/pwd", "pwd", NULL);
execl("/usr/bin/bash", "bash","test.sh", NULL);
exit(0);
}
#include <unistd.h>
int main()
{
//第一个参数,execlp带p的,可以使用环境变量PATH,无需写全路径
//后面的参数以列表形式(带l)告诉exec怎么执行
//以NULL结尾
execlp("ps", "ps", "-ef", NULL);
execlp("ls", "ls", "-a","-l", NULL);
exit(0);
}
#include <unistd.h>
int main()
{
//第一个参数,execv和execvp带v的,使用数组传参
//后面的参数以列表形式(带l)告诉exec怎么执行
//以NULL结尾
char *const argv[] = {"ps", "-ef", NULL};
execv("/bin/ps", argv);
// 带p的,可以使用环境变量PATH,无需写全路径
execvp("ps", argv);
exit(0);
}