system函数和exec函数族的使用
1.作用:
实现在一个进程中调用执行另外一个进程
2.system的用法
c
int system(const char *command)
参数: command --》你要执行的shell命令或者可执行程序
用法一:执行shell命令
用法二:执行另外一个可执行程序
比如:开发板上有一个madplay的程序,用来播放音频文件的
开发板本身没带扬声器(需要插耳机到开发板绿色的音频输出口)
播放音乐: madplay 音乐的路径名
madplay /1.mp3
代码实现:
system("madplay /1.mp3 &"); //madplay后台播放歌曲
system("madplay /1.mp3"); //madplay前台播放歌曲
前台播放无法实现暂停,继续,退出 -控制台被占用
暂停音乐: system("killall -STOP madplay"); //给madplay发送暂停信号
继续播放: system("killall -CONT madplay"); //给madplay发送继续信号
退出播放: system("killall -KILL madplay"); //给madplay发送杀死信号
小结:linux中给进程发送信号有两个命令可以使用
命令1: kill 信号的名字/信号的序号 进程的id号 比如: kill -9 5468
//给5468这个进程发送9号信号
kill -SIGKILL 5468 //给5468这个进程发送SIGKILL号信号
kill -KILL 5468 //给5468这个进程发送SIGKILL号信号
命令2: killall 信号的名字/信号的序号 进程的名字 比如: killall -9 hello
//给hello这个进程发送9号信号
killall -SIGKILL hello //给hello这个进程发送SIGKILL号信号
killall -KILL hello //给hello这个进程发送SIGKILL号信号
示例代码1:system执行shell命令
c
#include <stdlib.h>
#include <unistd.h>
/*
system执行shell命令
*/
int main(int argc, char const *argv[])
{
system("ls -l");
sleep(3);
system("pwd");
return 0;
}
示例代码2:system执行另外一个程序
c
// hello.c
#include <stdio.h>
int main()
{
while(1)
{
printf("hello world\n");
sleep(2);
}
return 0;
}
// system执行另外hello.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
/*
system执行另外一个进程(编译好的程序)
实现在一个进程中调用执行另外一个进程
*/
int main()
{
/*
system调用执行另外一个独立的进程分为两种情况
情况1:hello里面有死循环,会影响你当前进程后面的代码执行
解决方法1:让hello在后台执行,后台执行不会影响到后续的代码
解决方法2:借助今天学习fork函数,搞个子进程出来,通过子进程执行system
*/
//方法1:让hello在后台执行,后台执行不会影响到后续的代码
//system("./hello &"); //&符号的意思是后台执行hello
// for(;;)
// {
// printf("main main main,我的ID: %d\n",getpid());
// sleep(1);
// }
//方法2:借助fork函数,创建个子进程出来,通过子进程执行system
pid_t id;
id=fork();
if(id>0) //父进程
{
for(;;)
{
printf("main main main,我的ID: %d\n",getpid());
sleep(1);
}
}
else if(id==0) //子进程
{
system("./hello");
}
}
3.exec函数族的用法
特点:
- exec函数族里面的6个函数会替换你当前进程后面的代码,导致你当前进程后面的代码无法执行
- system函数不会影响当前进程执行后面的代码
c
int execl(char *path,char *arg,...);
参数:path --》你要执行的shell命令/程序的路径名
arg --》你的shell命令/程序的参数
int execlp(char *file,char *arg,...);
参数:file --》你只需要写shell命令/程序的名字即可
int execle(const char *path, const char *arg,
..., char *envp[]);
参数:path --》你要执行的shell命令/程序的路径名
arg --》你的shell命令/程序的参数
envp[] --》存放需要设置环境变量
int execv(const char *path, char *const argv[]);
参数:argv[] --》存放命令参数
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
char *const envp[]);
l --》参数以列表的形式逐一列举
p --》表示从系统的环境变量中去查找要执行的shell命令或者程序
e --》表示在执行命令的时候,可以顺便设置环境变量
允许改变子进程的环境变量,无后缀e时,子进程使用当前程序的环境
v --》参数需要使用指针数组存放
示例代码1:execl执行shell命令
c
#include <unistd.h>
/*
execl执行shell命令
实现在一个进程中调用执行另外一个进程
exec函数族:
l --》参数以列表的形式逐一列举
*/
int main(int argc, char const *argv[])
{
execl("/usr/bin/ls", "ls", "-l", NULL);
return 0;
}
示例代码2:execl执行另外一个程序
c
#include <unistd.h>
/*
execl执行另外一个程序
exec函数族:
l --》参数以列表的形式逐一列举
*/
int main(int argc, char const *argv[])
{
/* 既可用绝对路径,也用相对路径 */
execl("hello", "./hello", NULL);
return 0;
}
示例代码3:execlp的使用
c
#include <stdio.h>
#include <unistd.h>
/*
execlp的使用
实现在一个进程中调用执行另外一个进程
exec函数族:
l --》参数以列表的形式逐一列举
p --》表示从系统的环境变量中去查找要执行的shell命令或者程序
*/
int main(int argc, char const *argv[])
{
execlp("ls", "ls", "-l", "-a", NULL);
return 0;
}
示例代码4:execle的使用
c
#include <stdio.h>
#include <unistd.h>
/*
execle的使用
实现在一个进程中调用执行另外一个进程
exec函数族:
l --》参数以列表的形式逐一列举
p --》表示从系统的环境变量中去查找要执行的shell命令或者程序
e --》执行程序的时候,可以顺便设置那个程序的环境变量
*/
int main(int argc, char const *argv[])
{
// 定义自定义环境变量数组,必须以 NULL 结尾
char *const envp[] = {
"MY_VAR=HelloFromExecle",
"ANOTHER_VAR=12345",
NULL // 重要:环境变量数组必须以 NULL 结尾
};
printf("Before execle...\n");
// 调用 execle
// path: "/usr/bin/env" (要执行的程序路径)
// arg0: "env" (程序名,对应 argv[0])
// arg1: NULL (没有其他命令行参数,列表以 NULL 结尾)
// envp: 自定义的环境变量表
execle("/usr/bin/env", "env", NULL, envp);
// 如果 execle 成功,下面的代码不会执行
// 如果执行到这里,说明 execle 出错了
perror("execle failed");
return 1;
}
示例代码5:execv的使用
c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h> // for exit
int main(int argc, char const *argv[])
{
printf("Before execv...\n");
// 定义参数数组,必须以 NULL 结尾
// 对应命令: /bin/ls -l -a
char *const args[] = {
"/bin/ls", // argv[0]: 程序名(通常也是路径)
"-l", // argv[1]: 第一个参数
"-a", // argv[2]: 第二个参数
NULL // 重要:参数数组必须以 NULL 结尾
};
// 调用 execv
// path: "/bin/ls"
// argv: args 数组
execv("/bin/ls", args);
// 如果 execv 成功,下面的代码不会执行
// 如果执行到这里,说明出错了
perror("execv failed");
return 1;
}
示例代码6:exec和system的区别
c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
/*
exec和system的区别
*/
int main()
{
#if 1
//exec
printf("1. 这行会打印\n");
// execlp: 自动从 PATH 查找 ls
// 注意:如果成功,下面的 printf 永远不会执行!
execlp("ls", "ls", "-l", "/tmp", NULL);
// 只有当 execlp 出错时,才会执行到这里
perror("execlp failed");
printf("2. 这行通常不会打印(除非出错)\n");
#else
printf("1. 这行会打印\n");
// system 会阻塞,直到 ls 命令执行完毕
int ret = system("ls -l /tmp");
printf("2. 这行一定会打印,system 返回值为: %d\n", ret);
#endif
return 0;
}