进程 – exec函数族
进程调用exec函数族执行某个程序
进程当前内容被指定的程序替换
实现让父子进程执行不同的程序
- 父进程创建子进程
- 子进程调用exec函数族
- 父进程不受影响
进程 – execl / execlp
#include <unistd.h>
int execl(const char *path, const char *arg, NULL);
int execlp(const char *file, const char *arg,NULL);
成功时执行指定的程序;
- 失败时返回EOF
- path 执行的程序名称,包含路径
- arg… 传递给执行的程序的参数列表
- file 执行的程序的名称,在PATH中查找
进程创建 – execl(p) – 示例
#include <stdio.h>
#include <unistd.h>
int main(){
printf("before exec\n");
if(execlp("ls","ls","-a","-l","./",NULL)<0){
perror("execl");
}
}
进程 – execv / execvp
#include <unistd.h>
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
- 成功时执行指定的程序;
- 失败时返回EOF arg… 封装成指针数组的形式
进程创建 – execv(p) – 示例
#include <stdio.h>
#include <unistd.h>
int main(){
char *agv[] = {"ls","-a","-l","./",NULL};
if(execv("/bin/ls",agv)<0){
perror("execv");
}
}
进程 – system
#include <stdlib.h>
int system(const char *command);
- 成功时返回命令command的返回值;
- 失败时返回EOF 当前进程等待command执行结束后才继续执行
守护进程
- 守护进程(Daemon Process)是Linux三种进程类型之一
- 是 Linux 中的后台服务进程
- 是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件
守护进程特点
- 特殊的孤儿进程
- 始终在后台运行
- 独立于任何终端
- 周期性的执行某种任务或等待处理特定事件
守护进程 –相关概念
- 进程组(Process Group): 进程集合,每个进程组有一个组长(Leader),其进程 ID 就是该进程组 ID。
- 会话(Session): 进程组集合,每个会话有一个组长,其进程 ID 就是该会话组 ID。
- 控制终端(Controlling Terminal):每个会话可以有一个单独的控制终端,与控制终端连接的 Leader 就是控制进程(Controlling Process)。
守护进程创建
(一)
-
创建子进程,父进程退出
if (fork() > 0) {
exit(0);
}
- 子进程变成孤儿进程,被init进程收养
- 子进程在后台运行
(二)
-
子进程创建新会话
if (setsid() < 0) {
exit(-1);
}
- 子进程成为新的会话组长
- 子进程脱离原先的终端
(三)
-
更改当前工作目录
chdir(“/”);
chdir(“/tmp”);
- 守护进程一直在后台运行,其工作目录不能被卸载
- 重新设定当前工作目录cwd
(四)
-
重设文件权限掩码
if (umask(0) < 0) {
exit(-1);
}
- 文件权限掩码设置为0
- 只影响当前进程
(五)
-
关闭打开的文件描述符
int i;
for(i=0; i<3; i++) {
close(i);
}
- 关闭所有从父进程继承的打开文件
- 已脱离终端,stdin / stdout / stderr无法再使用
守护进程 – 示例1
创建守护进程,每隔1秒将系统时间写入文件time.log
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
int main()
{
pid_t pid;
FILE *fp;
time_t t;
int i;
if ((pid = fork()) < 0)
{
perror(“fork”);
exit(-1);
}
else if (pid > 0)
{
exit(0);
}
setsid();
umask(0);
chdir(“/tmp”);
for (i=0; i< 3; i++)
{
close(i);
}
if ((fp = fopen(“time.log”, “a”)) == NULL)
{
perror(“fopen”);
exit(-1);
}
while(1)
{
time(&t);
fprintf(fp, “%s”, ctime(&t));
fflush(fp);
sleep(1);
}
}
gdb调试多进程
gdb是安装在Linux系统下的调试工具,编译可执行文件时加上参数"-g"才可以被调试。
set follow-fork-mode child 设置GDB调试子进程
set follow-fork-mode parent 设置GDB调试父进程
set detach-on-fork on/off 设置GDB跟踪调试单个进程或多个
on: 只调试父进程或子进程的其中一个,(根据follow-fork-mode来决定),这是默认的模式
off:父子进程都在gdb的控制之下,其中一个进程正常调试(根据follow-fork-mode来决定),另一个进程会被设置为暂停状态。
info inferiors 显示GDB调试的进程
inferiors 进程序号(1,2,3....) 切换GDB调试的进程