1、fork函数
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
printf("before fork1\n");
printf("before fork2\n");
printf("before fork3\n");
printf("before fork4\n");
printf("before fork5\n");
printf("before fork6\n");
pid_t pid1;
pid1 = fork();
if (pid1 == -1)
{
perror("fork error");
exit(1);
}
else if (pid1 == 0) // 子进程
{
printf("---child is created---\n");
}
else if (pid1 > 0)
{
printf("---parent process--- : my child is %d\n", pid1);
}
printf("============end of file\n");
return 0;
}
1、fork函数循环创建n个子进程
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("before fork1\n");
printf("before fork2\n");
printf("before fork3\n");
printf("before fork4\n");
printf("before fork5\n");
printf("before fork6\n");
int i;
pid_t pid1;
for (i = 0; i < 5; ++i)
{
pid1 = fork();
if (pid1 == -1)
{
perror("fork error");
exit(1);
}
else if (pid1 > 0)
{
if (i == 0)
printf("parent process: %d\n", getpid());
usleep(1);
}
else
{
printf("I'm %d child procee: %d myparentpid %d\n", i + 1, getpid(), getppid());
break;
}
}
printf("====end of file====\n");
return 0;
}
1、getpid函数
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
printf("before fork1\n");
printf("before fork2\n");
printf("before fork3\n");
printf("before fork4\n");
printf("before fork5\n");
printf("before fork6\n");
pid_t pid1;
pid1 = fork();
if (pid1 == -1)
{
perror("fork error");
exit(1);
}
else if (pid1 == 0) // 子进程
{
printf("---child is created---\n");
printf("my pid: %d, my parent pid: %d\n", getpid(), getppid());
}
else if (pid1 > 0)
{
printf("---parent process--- : my child is %d\n", pid1);
printf("my pid: %d, my parent pid: %d\n", getpid(), getppid());
}
printf("============end of file\n");
return 0;
}
1、父子进程共享 不共享
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
// 定义1个全局变量
int var = 100; // 测试父子进程是否共享全局变量
// 不共享, 读时共享, 写时复制
int main(int argc, char *argv[])
{
pid_t pid;
pid = fork();
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
// 父进程
var = 288;
printf("parent, var = %d\n", var);
printf("I'm parent pid = %d, getppid = %d\n", getpid(), getppid());
}
else if (pid == 0)
{
// 子进程
// var = 200;
printf("I'm child pid = %d, ppid = %d\n", getpid(), getppid());
printf("child, var = %d\n", var);
}
return 0;
}
2、execl换壳函数 -后台进程打印到文件
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
// 重定向输出--某文件
int fd1 = open(argv[1], O_RDWR | O_CREAT, 0644);
if (fd1 == -1)
{
perror("open error");
exit(1);
}
int fd2 = dup2(fd1, STDOUT_FILENO);
if (fd2 == -1)
{
perror("dup2 error");
exit(1);
}
// 执行ps aux
int ret = execlp("ps", "ps", "-a", "-u", "-x", NULL);
if (ret == -1)
{
perror("execlp error");
exit(1);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char *argv[])
{
printf("----before fork1----\n");
printf("----before fork2----\n");
printf("----before fork3----\n");
printf("----before fork4----\n");
printf("----before fork5----\n");
pid_t pid;
int ret;
pid = fork();
if (pid == -1)
{
perror("fork error\n");
exit(1);
}
else if (pid > 0)
{
sleep(1);
printf("Father process: %d, child process: %d\n", getpid(), pid);
}
else
{
printf("child process: %d, myfather process: %d\n", getpid(), getppid());
// ret = execl("./test", "./test", NULL);
// ret = execl("./", "test", NULL);
ret = execl("/bin/ls", "/bin/ls", NULL);
if (ret == -1)
{
perror("execlp error");
exit(1);
}
}
printf("====end of file====\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char *argv[])
{
printf("----before fork1----\n");
printf("----before fork2----\n");
printf("----before fork3----\n");
printf("----before fork4----\n");
printf("----before fork5----\n");
pid_t pid;
int ret;
pid = fork();
if (pid == -1)
{
perror("fork error\n");
exit(1);
}
else if (pid > 0)
{
sleep(1);
printf("Father process: %d, child process: %d\n", getpid(), pid);
}
else
{
printf("child process: %d, myfather process: %d\n", getpid(), getppid());
// ret = execlp("ls", "ls", "-l", "-h", NULL); // NULL代表参数结束(手动加)
ret = execlp("date", "date", NULL);
if (ret == -1)
{
perror("execlp error");
exit(1);
}
}
printf("====end of file====\n");
return 0;
}
3、 孤儿进程
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
printf("I'm parent, my pid is = %d\n", getpid());
sleep(9);
printf("----parent going to die----\n");
}
else
{
while(1)
{
printf("I'm child, my parent pid = %d\n", getppid());
sleep(1);
}
}
return 0;
}
3、僵尸进程
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
while(1)
{
printf("I'm parent, pid = %d, my son pid = %d\n", getpid(), pid);
sleep(1);
}
}
else
{
printf("child, my parent = %d, going to sleep 10s\n", getppid());
sleep(10);
printf("----child die----\n");
}
return 0;
}
4、wait回收子进程 查看死因
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid, wpid;
pid = fork();
int status; // 记录子进程死亡原因
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
wpid = wait(&status);
if (wpid == -1)
{
perror("wait error");
exit(1);
}
printf("----parent wait(%d) finished\n", wpid); // 阻塞等待回收子进程(子不死, 父不回收)
// 查看子进程死亡原因
if (WIFEXITED(status)) // 子进程正常死亡的
printf("子进程return值: %d\n", WEXITSTATUS(status));
else if (WIFSIGNALED(status)) // 子进程被信号杀死的(非正常死亡)
printf("子进程被%d号信号杀死\n", WTERMSIG(status));
}
else
{
printf("---child, myid = %d, my parent = %d, going to sleep 10s\n", getpid(), getppid());
sleep(10);
printf("-----------------child die------------------\n");
return 73;
}
return 0;
}
4、waitpid指定回收子进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
// 循环创建多个子进程
pid_t pid, wpid;
int i;
// int status; // 查看子进程死亡原因
for (i = 0; i < 5; ++i)
{
pid = fork();
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
if (i == 0)
printf("I'm parent %d\n", getpid());
// 父进程 // 指定回收第3个子进程
if (i == 2)
{
sleep(5);
wpid = waitpid(pid, NULL, WNOHANG); // 非阻塞式回收
if (wpid == -1)
{
perror("waitpid error");
exit(1);
}
printf("I'm parent, wait a child finish : %d\n", wpid); // 子进程没死
}
}
else
{
// 子进程
sleep(i);
printf("I'm %dth child mypid = %d\n", i + 1, getpid());
break;
}
}
return 0;
}
4、waitpid无差别回收子进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
// 循环创建多个子进程
pid_t pid, wpid;
int i;
// int status; // 查看子进程死亡原因
for (i = 0; i < 5; ++i)
{
pid = fork();
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
// 父进程
wpid = waitpid(-1, NULL, WNOHANG); // 非阻塞式回收
if (wpid == -1)
{
perror("waitpid error");
exit(1);
}
printf("I'm parent, wait a child finish : %d\n", wpid); // 子进程没死
}
else
{
// 子进程
sleep(i);
printf("I'm %dth child\n", i + 1);
break;
}
}
return 0;
}
5、waitpid阻塞回收多个子进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
// 循环创建多个子进程
pid_t pid, wpid;
int i;
// int status; // 查看子进程死亡原因
for (i = 0; i < 5; ++i)
{
pid = fork();
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
if (i == 0)
printf("I'm parent %d\n", getpid());
}
else
{
// 子进程
sleep(i);
printf("I'm %dth child mypid = %d\n", i + 1, getpid());
break;
}
}
if (i == 5) // 只有父进程才会1步1步++到5退出循环, 子进程直接break的
{
// 1次wait/waitpid只能回收1个子进程 形参>0指定回收某个 -1回收任意一个子进程
while ((wpid = waitpid(-1, NULL, 0)) > 0) // 阻塞回收
{
if (wpid == -1)
{
perror("waitpid error");
exit(1);
}
printf("waitpid(%d)\n", wpid);
}
}
return 0;
}
5、waitpid非阻塞回收多个子进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
// 循环创建多个子进程
pid_t pid, wpid;
int i;
// int status; // 查看子进程死亡原因
for (i = 0; i < 5; ++i)
{
pid = fork();
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
if (i == 0)
printf("I'm parent %d\n", getpid());
}
else
{
// 子进程
sleep(i);
printf("I'm %dth child mypid = %d\n", i + 1, getpid());
break;
}
}
if (i == 5) // 只有父进程才会1步1步++到5退出循环, 子进程直接break的
{
// 1次wait/waitpid只能回收1个子进程 形参>0指定回收某个 -1回收任意一个子进程
while ((wpid = waitpid(-1, NULL, WNOHANG)) >= 0) // 非阻塞回收
{
sleep(1);
if (wpid == -1)
{
perror("waitpid error");
exit(1);
}
printf("waitpid(%d)\n", wpid);
}
}
return 0;
}
阶段练习(fork创建3子进程, execl分别执行, 父进程回收)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
pid_t pid, wpid;
int i, ret1, ret2, ret3;
for (i = 0; i < 3; ++i)
{
pid = fork();
if (pid == -1)
{
perror("fork error");
exit(1);
}
else if (pid > 0)
{
if (i == 0)
printf("Parent = %d\n", getpid());
}
else
{
printf("I'm %dth child = %d, myparent = %d\n", i + 1, getpid(), getppid());
sleep(i);
if (i == 0)
{
ret1 = execlp("ps", "ps", NULL);
if (ret1 == -1)
{
perror("execl error");
exit(1);
}
}
else if (i == 1)
{
ret2 = execl("./a.out", "./a.out", NULL);
if (ret2 == -1)
{
perror("execl error");
exit(1);
}
}
else
{
ret3 = execl("./b.out", "./b.out", NULL);
if (ret3 == -1)
{
perror("execl error");
exit(1);
}
}
// break;
}
}
if (i == 3) // 父进程回收3个子进程
{
while ((wpid = waitpid(-1, NULL, WNOHANG)) >= 0) // 非阻塞回收
{
printf("I'm parent waitpid %d\n", wpid);
sleep(1);
}
}
return 0;
}