day 29 进程exec函数族 ,进程实现无人机模块,exec实现minishell
1.excel函数族与system
当进程调用一种exec函数时,该进程的
用户空间代码和数据完全被新程序替换,无新进程的创建
第一个参数可以是编译后的文件的地址
例
gcc exec.c -o app
"./app"作为第一个参数,./app作为第二个参数,这样可以替换为自己写的程序
execl("./app", "./app", NULL);
l:参数以列表形式传递
v:参数以指针数组形式传递
p:在系统路径下找要执行的代码
#include <stdio.h>
#include<unistd.h>
int main()
{
char *arg[] = {"top",NULL};
execv("/usr/bin/top",arg);//第一个参数是这个命令的所在地址,后面的参数打包在指针数组里面
execlp("top","top",NULL);//第一个直接写命令就行,不用写准确地址,
execl("/usr/bin/top","top",NULL);,第一个是地址,后面的要写在控制台输入的指令,空格作为分割,每个都是独立的参数
execvp("top",arg);
return 0;
}
system
直接传在终端输入的指令作为参数。创建了新的进程(与exec的区别)system("./app");
使用fork和exec实现system
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
printf("before system\n");
pid_t pid = fork();
if (pid > 0)
{
wait(NULL);
}
else if (0 == pid)
{
execl("./app", "./app", NULL);
}
else
{
perror("fail fork");
}
printf("after system\n");
return 0;
}
2 .模仿无人机实现以下
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main(int argc,char *argv[])
{
int i =0;
pid_t pid = 0;
for(i = 0; i<5;++i)
{
pid = fork();
if(pid == 0)//注意这一块,必须判断,让子进程出去
{
break;
}
}
if(pid > 0)
{
for(int j = 0;j<5;++j)
{
wait(NULL);
}
}
else if(0 == pid)
{
switch(i)
{
case 0:
while(1)
{
printf("主模块正在工作\n");
sleep(1);
}
break;
case 1:
while(1)
{
printf("图像采集模块正在工作\n");
sleep(1);
}
break;
case 2:
while(1)
{
printf("图像发送\n");
sleep(1);
}
break;
case 3:
while(1)
{
printf("命令接收\n");
sleep(1);
}
break;
case 4:
while(1)
{
printf("命令执行\n");
sleep(1);
}
break;
}
}
return 0;
}
3 minishell
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
void show_cmd_line()
{
char path[512] = {0};
getcwd(path,sizeof(path));//获得地址
fprintf(stdout,"XuHeng@ubuntu:%s$",path);
fflush(stdout);
return;
}
void get_user_cmd(char *cmd ,int len)
{
fgets(cmd ,len ,stdin);
cmd[strlen(cmd)-1] = '\0';//fgets\n 后有个\0,gets()直接将\n换位\0
return;
}
void strtok_cmd(char *cmd, char **arg)
{
int i = 0;
arg[i] = strtok(cmd ," ");//注意用双引号
while(NULL != arg[i])
{
++i;
arg[i] = strtok(NULL ," ");//只剩最后一段带\0他会自动分。
}
return;
}
int exec_cmd(char **arg)
{
pid_t pid = fork();
if(pid>0)
{
wait(NULL);
}
else if(pid == 0)
{
execvp(arg[0],arg);//成功无法返回
printf("fail exec\n");//?
exit(1);
}
return 0;
}
int main(int argc , char *argv[])
{
char cmd[512] = {0};
char *arg[512] = {NULL};
while(1)
{
show_cmd_line();
get_user_cmd(cmd ,sizeof(cmd));
strtok_cmd(cmd , arg);
if(0 == strcmp(arg[0],"exit"))
{
break;
}
else if( 0== strcmp (arg[0] , "cd"))
{
chdir(arg[1]);
continue;
}
exec_cmd(arg);
}
return 0;
}