长生栈 长生栈
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Living Team

编程技术分享
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 文件操作

  • Linux进程和线程

    • 进程创建
    • 在进程中启动程序
      • 进程的操作
      • exec函数族
        • execve函数
        • execve函数举例
        • 结论
      • 示例代码
    • 等待进程结束
    • 线程简介
    • 多线程编程举例
    • 线程同步
    • 线程属性
  • Linux信号

  • 进程间通信

  • Socket

  • C语言
  • Linux进程和线程
DC Wang
2023-02-17
目录

在进程中启动程序

# 在进程中启动程序

# 进程的操作

传统Uinx模型中有两个创建和修改进程的操作。

  • fork:用来创建一个新的进程,此进程几乎是当前进程的一个完全拷贝

  • exec:可以在进程中用另外的程序来替换掉当前进程运行的程序

# exec函数族

exec函数实际是包含了六个函数的函数族

#include<unistd.h>
int execl(const char* path, const char* arg, …);
int execlp(const char* file, const char* arg, …);
int execle(const char* path, const char* arg, char* const envp[]);
int execv(const char* path, char* const argv[]);
int execvp(const char* file, char* const argv[]);
int execve(const char* path, char* const argv[], char* const envp[]);
1
2
3
4
5
6
7

# execve函数

#include<unistd.h>
int execve(const char* path, char* const argv[] , char* const envp[]);
1
2
  • path:可执行文件路径

  • argv[]:完整的参数列表,包含argv[0],必须以NULL结束

  • envp[]:环境变量,可省

# execve函数举例

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
	char *argv[] = {"/", NULL};  
	if(execve("/bin/ls", argv, NULL) == -1) 
	{
		perror("execve");
		exit(EXIT_FAILURE);
	}
	puts("shouldn't get here");
	exit(EXIT_SUCCESS);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ./execve
1.txt  2.txt  3.txt  execve
1
2

# 结论

  • “shouldn‘t get here”根本没有执行。

    这是因为执行到execve函数时,进程的代码部分已经用新程序替换了,不会留下调用进程的任何痕迹。

    也就是说,exec函数族一旦执行成功,就不会返回它的调用者(失败返回-1,并设置errno)。

# 示例代码

利用fork建立一个子进程,在此子进程中执行显示当前目录下所有文件的命令,同时父进程中显示父进程的PID号。

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
	pid_t child;		
	int status;
	if((child = fork()) == -1) {	
		perror("fork");
		exit(EXIT_FAILURE);
	} else if(child == 0) {	
		puts("in child");
		char *argv[] = {"ls -l", NULL};  
		if(execve("/bin/ls", argv, NULL) == -1) {
			perror("execve");
			exit(EXIT_FAILURE);
		}	
		exit(EXIT_SUCCESS);
	} else {
		waitpid(child, &status, 0); 
		puts("\nin parent");
		printf("\tparent pid = %d\n", getpid());
		printf("\tparent ppid = %d\n", getppid());
	}
	exit(EXIT_SUCCESS);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

执行结果

$ ./forkwait
in child
1.txt  2.txt  3.txt  execve  forkwait

in parent
        parent pid = 2576
        parent ppid = 2138
1
2
3
4
5
6
7
编辑 (opens new window)
#C#Linux#进程
上次更新: 2023/02/18, 10:09:42
进程创建
等待进程结束

← 进程创建 等待进程结束→

最近更新
01
ESP32-网络摄像头方案
06-14
02
ESP32-PWM驱动SG90舵机
06-14
03
ESP32-实时操作系统freertos
06-14
更多文章>
Theme by Vdoing | Copyright © 2019-2025 DC Wang All right reserved | 辽公网安备 21021102001125号 | 吉ICP备20001966号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式