一、使用system函数调用进程
cpp
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char const *argv[])
{
//使用标准函数创建自进程
/*
const char *__command 使用linux命令直接创建一个子进程
return:成功返回0 失败返回失败编号
int system (const char *__command)
*/
int sysR=system("ping -c 10 www.lxl.com");
if (sysR != 0 )
{
perror("system");
exit(EXIT_FAILURE);
}
return 0;
}
makefile
cpp
CC:=gcc
system_test:system_test.c
-$(CC) -o $@ $^
-./$@
-rm ./$@
二、进程处理相关系统调用
1、main函数说明

2、fork创建子进程
cpp
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc, char const *argv[])
{
//调用fork之前 代码都在父进程中运行
printf("海哥教老学员%d春暖花开\n",getpid());
//使用fork创建子进程
/*
不需要传参
return int 进程号
【1】:-1出错
【2】:父进程中表示子进程的PID
【3】:子进程中显示为0
__pid_t fork (void)
*/
pid_t pid = fork();
//从fork之后 所有的代码都是在父进程中各自执行一次的
//printf("%d\n",pid);
if (pid < 0)
{
printf("新学员加入失败\n");
return 1;
}
else if (pid == 0)
{
//执行单独子进程代码
printf("新学员%d加入成功,他是老学员%d推荐的\n",getpid(),getpid());
}
else
{
//执行单独父进程代码
printf("老学员%d继续深造,他推荐了%d\n",getpid(),pid);
}
return 0;
}
makefile
cpp
fork_test:fork_test.c
-$(CC) -o $@ $^
-./$@
-rm ./$@
3、使用fork复制文件描述符
cpp
#include<sys/stat.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
int main(int argc, char const *argv[])
{
//fork之前 父进程单独进
int fd = open("io.txt",O_CREAT | O_WRONLY |O_APPEND,0644);
if (fd == -1)
{
perror("open");
exit(EXIT_FAILURE);
}
char buffer[1024];//缓冲区存放写出的数据
pid_t pid = fork();
if (pid < 0)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
//子进程代码
strcpy(buffer,"这是子进程写入的数据!\n");
}
else
{
//父进程代码
sleep(1);
strcpy(buffer,"这是父进程写入的数据!\n");
}
//父子进程都要执行的代码
ssize_t bytes_write = write(fd,buffer,strlen(buffer));
if (bytes_write == -1)
{
perror("write");
close(fd);
exit(EXIT_FAILURE);
}
printf("写入数据成功\n");
//使用完毕之后关闭
close(fd);
if (pid == 0)
{
printf("子进程写入完毕,并释放文件描述符\n");
}
else
{
printf("父进程写入完毕,并释放文件描述符\n");
}
return 0;
}
makefile
cpp
fork_fd_test:fork_fd_test.c
-$(CC) -o $@ $^
-./$@
-rm ./$@
4、execve
exec系列函数可以在同一进程中跳转执行另外一个程序
(1)execve单独使用
cpp
//erlou.cpp内容
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc, char const *argv[])
{
if (argc < 2)
{
printf("参数不够,不能上二楼");
return 1;
}
printf("我是%s 编号%d 父进程编号%d,我跟海哥上二楼了\n",argv[1],getpid(),getpid());
return 0;
}
makefile
cpp
erlou:erlou.c
-$(CC) -o $@ $^
cpp
//execve_test.cpp内容
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc, char const *argv[])
{
//跳转之前
char *name="banzhang";
printf("我是%s 编号%d 父进程编号%d,我现在还在一楼\n",name,getpid(),getpid());
/*
const char *__path 执行程序的路径
char *const __argv[] 传入的参数与main函数中argv是对应的
【1】第一个参数固定是程序的名称
【2】执行程序需要传入的参数
【3】最后一个参数一定是NULL
char *const __envp[] 传递的环境变量
【1】环境变量参数:key=value
【2】最后一个参数一定是NULL
return 成功根本没办法返回 下面的代码没有意义,失败返回 -1
跳转前后只有进程号保留下来,别的变量都删除了
int execve(const char *__path, char *const __argv[], char *const __envp[])
*/
//执行跳转
char *args[]={"/home/lxl/process_test/erlou",name,NULL};
char *envs[]={NULL};
int re= execve(args[0],args,envs);
if (re == -1)
{
printf("你没有机会上二楼");
return 1;
}
//此处的代码没有意义,因为程序跳转了,不会再往下执行了
return 0;
}
cpp
execve_test:execve_test.c
-$(CC) -o $@ $^
-./$@
-rm ./$@
(2)execve+fork
可以fork和exec共同使用,实现场景老学员推荐新学员在二楼学习,自己保持不变。
cpp
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc, char const *argv[])
{
//跳转之前
char *name="banzhang";
printf("我是%s 编号%d 父进程编号%d,我现在还在一楼\n",name,getpid(),getppid());
/*
const char *__path 执行程序的路径
char *const __argv[] 传入的参数与main函数中argv是对应的
【1】第一个参数固定是程序的名称
【2】执行程序需要传入的参数
【3】最后一个参数一定是NULL
char *const __envp[] 传递的环境变量
【1】环境变量参数:key=value
【2】最后一个参数一定是NULL
return 成功根本没办法返回 下面的代码没有意义,失败返回 -1
跳转前后只有进程号保留下来,别的变量都删除了
int execve(const char *__path, char *const __argv[], char *const __envp[])
*/
//执行跳转
char *args[]={"/home/lxl/process_test/erlou",name,NULL};
char *envs[]={NULL};
int re= execve(args[0],args,envs);
if (re == -1)
{
printf("你没有机会上二楼");
return 1;
}
//此处的代码没有意义,因为程序跳转了,不会再往下执行了
return 0;
}
makefile
cpp
fork_execve_test:fork_execve_test.c
-$(CC) -o $@ $^
-./$@
-rm ./$@
5、waitpid
cpp
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main(int argc, char const *argv[])
{
//fork之前
int subprocess_status;
printf("老学员%d在校区\n",getpid());
pid_t pid = fork();
if (pid < 0)
{
perror("fork");
return 1;
}
else if (pid == 0)
{
char* args[]={"/usr/bin/ping","-c","10","www.lxl.com",NULL};
char*envs[]={NULL};
printf("新学员%d联系老学员%d 10次\n",getpid(),getppid());
int exeR = execve(args[0],args,envs);
if (exeR < 0)
{
perror("execve");
return 1;
}
}
else
{
printf("老学员%d等待新学员%d联系\n",getpid(),pid);
waitpid(pid,&subprocess_status,0);
}
printf("老学员等待新学员联系完成\n");
return 0;
}
makefile
cpp
waitpid_test:waitpid_test.c
-$(CC) -o $@ $^
-./$@
-rm ./$@