浅析fork函数、exec函数和pthread函数
函数 浅析 exec fork pthread
2023-06-13 09:12:18 时间
1、fork函数,exec函数和pthread函数的机理
在linux中,每个进程都使用一个唯一的整数形式的进程标识符来标识。
1.1 fork()
Fork()函数是创建新进程的函数,即通过fork()系统调用,可创建新进程。新进程复制原来进程的地址空间,这种机制允许父子进程之间相互通信。两个进程都继续执行系统调用fork()函数之后的指令。但是不同的是,对于新创建的进程,系统调用fork()之后的返回值为0,对于原来的父进程,返回值大于0,如果创建新进程失败,则返回一个负值。使用fork函数得到的子进程从父进程继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。
1.2 exec()
exec()函数用于将一个进程替换为一个新的进程。exec函数的函数执行成功后不会返回,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只有进程ID等一些表面上的信息仍保持原样。调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。Exec()本身并没有创建新进程,只是将原进程分配了新的数据段和堆栈段。
Exec()函数一般用于系统调用fork()函数之后,新进程会使用exec()函数来代替父进程的内存空间系统通过调用exec()函数将二进制文件装入内存,并开始执行。在这个过程中,我们可以改变创建的新进程来执行一个新的程序。
1.3 pthread
pthread和上述两个函数不同,pthread和线程有关。Pthread是为线程创建和同步定义的API,在一个进程中可以有多个线程,每个线程都有自己的栈和调度信息还有私有信息等。
Pthread含有很多函数:
- pthread_t 是pthread的线程ID
- pthread_create()用于创建新的线程
- pthread_equal()用于比较两个线程id是否相等
- pthread_self() 用于获取当前线程的id
- pthread_exit() 线程调用该函数主动退出线程
- pthread_join() 用于线程同步,以阻塞的方式等待指定线程结束
通过上述函数我们可以对线程进行控制,也可以创建新的线程。
2、举例说明:
2.1 需求:
- 1.进程A 创建子进程B
- 2.子进程B与父进程A分别对应不同的exe(进程A打印Hello word, 进程B实现sum累加)
- 3.进程B具有两线程,其中主线程创建新的线程来实现sum累加(从1累加到参数x) 2.2 代码 1、 main_process.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc,char ** argv){
pid_t pid;
pid=fork();
if(pid<0) // error
{
printf("there have something wrong\n");
}
if(pid>0) // father
{
printf("this is main process\n");
}
if(pid==0) // son
{
printf("this is new processs");
// execl( "/root/fork/2","10",NULL);
if( execl( "/root/fork/new_process",argv[1],NULL) < 0)
{
perror("execv error ");
}
}
return 0;
}
- 2、 new_process.c
#include<stdio.h>
#include<pthread.h>
int sum;
void *runner(void *param);
int main(int argc,char *argv[])
{
printf("this is new process");
pthread_t tid; // the thread identifuer
pthread_attr_t attr; // set thread attributes
pthread_attr_init(&attr); // default attributes
pthread_create(&tid,&attr,runner,argv[1]);// create new thread
pthread_join(tid,NULL);
printf("the sum is %d\n",sum);
}
void *runner(void *param)
{
int i,upper=atoi(param);
sum=0;
for(i=0;i<=upper;i++)
sum=sum+i;
pthread_exit(0);
}
- 2.3 代码分析:
- 主程序进入main函数之后,创建一个进程,给这个进程分配内存和该进程数据段和堆栈所需的物理空间。
- 之后主函数使用fork()函数创建新进程,新进程和原进程使用相同的内存,子进程的代码段、数据段、堆栈都是指向父进程的物理空间。
- 父进程输出‘helloworld‘,子进程使用exec函数调用new_process.c,这时进程的数据段,堆栈等内容都被修改,从而我们设立新进程为new_process程序。
- 在执行new_process函数时,我们使用Pthread函数创立了一个新的线程,该线程与原线程享用相同的公用数据,进程信息。同时也有自己的独立数据。在代码里面,新线程实现累加功能,并把累加的结果赋给共用数据sum。
相关文章
- 在 View 上使用挂起函数 | 实战
- 超越ReLU却鲜为人知,3年后被挖掘:BERT、GPT-2等都在用的激活函数
- python转置矩阵函数_对python 矩阵转置transpose的实例讲解
- sendfile函数–零拷贝
- 【Shell】算术运算符、流程控制、函数使用、数组以及加载其它文件的变量
- 【组合数学】生成函数 ( 线性性质 | 乘积性质 )
- 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | exec_utils.cc 中执行 Dex 编译为 Oat 文件的 Exec 和 ExecAndReturnC函数 )
- Oracle 中 table 函数的应用浅析
- 函数TEXT – EXCEL单元格中日期格式转换为文本格式详解编程语言
- 基于SQLServer的函数编写实践(sqlserver写函数)
- MySQL中如何使用上月1号函数(mysql上月1号函数)
- 浅析jQuery的链式调用之each函数
- 浅析Java中Split函数的用法技巧
- 浅析stl序列容器(map和set)的仿函数排序
- js函数与php函数的区别实例浅析
- 浅析C/C++中sort函数的用法
- Java函数式编程(二):集合的使用