首页 > 系统相关 >linux下进程和线程的区别和联系

linux下进程和线程的区别和联系

时间:2023-03-02 22:35:25浏览次数:40  
标签:fork 调用 exec 线程 内存 linux 进程 vfork

进程用fork()或者vfork()生成(vfork是专门为了加载其他程序的子程序而优化的,随着fork()的优化,vfork已经被优化)

fork()生成的子进程与父进程共享代码区内存,对于其他内存

fork()之后常常伴随着 exec(), 这会用新程序替换进程的代码段,并重新初始化其 数据段、堆段和栈段。大部分现代 UNIX 实现(包括 Linux)采用两种技术来避免这种浪费。

1. 内核(Kernel)将每一进程的代码段标记为只读,从而使进程无法修改自身代码。这 样,父、子进程可共享同一代码段。系统调用 fork()在为子进程创建代码段时,其所 构建的一系列进程级页表项(page-table entries)均指向与父进程相同的物理内存页帧。

2.对于父进程数据段、堆段和栈段中的各页,内核采用写时复制(copy-on-write)技术 来处理。([Bach, 1986]和[Bovert & Cersati, 2005]描述了写时复制的实现。)最初,内核 做了一些设置,令这些段的页表项指向与父进程相同的物理内存页,并将这些页面自 身标记为只读。调用 fork()之后,内核会捕获所有父进程或子进程针对这些页面的修 改企图,并为将要修改的(about-to-be-modified)页面创建拷贝。系统将新的页面拷 贝分配给遭内核捕获的进程,还会对子进程的相应页表项做适当调整。从这一刻起,父、子进程可以分别修改各自的页拷贝,不再相互影响。图 24-3 展示了写时复制技术。

 

类似于 fork(),vfork()可以为调用进程创建一个新的子进程。然而,vfork()是为子进程立 即执行 exec()的程序而专门设计的。

 

vfork()因为如下两个特性而更具效率,这也是其与 fork()的区别所在。

1. 无需为子进程复制虚拟内存页或页表。相反,子进程共享父进程的内存,直至其成功 执行了 exec()或是调用_exit()退出。

2. 在子进程调用 exec()或_exit()之前,将暂停执行父进程。 这两点还另有深意:由于子进程使用父进程的内存,因此子进程对数据段、堆或栈的任 何改变将在父进程恢复执行时为其所见。此外,如果子进程在 vfork()与后续的 exec()或_exit() 之间执行了函数返回,这同样会影响到父进程。 

vfork()的语义在于执行该调用后,系统将保证子进程先于父进程获得调度以使用 CPU。

 

线程:

类似于 fork()和 vfork(),Linux 特有的系统调用 clone()也能创建一个新进程。与前两者不 同的是,后者在进程创建期间对步骤的控制更为精准。clone()主要用于线程库的实现。由于 clone()有损于程序的可移植性,故而应避免在应用程序中直接使用。

 

 

 

大体上说来,fork()相当于仅设置 flags 为 SIGCHLD 的 clone()调用,而 vfork()则对应于设 置如下 flags 的 clone():

CLONE_VM | CLONE_VFORK | SIGCHLD

 

标签:fork,调用,exec,线程,内存,linux,进程,vfork
From: https://www.cnblogs.com/woodx/p/17173823.html

相关文章

  • Linux SO_REUSEPORT与SO_REUSEADDR
    SO_REUSEADDR一般来说,一个端口释放后会等待两分钟之后才能再被使用,SO_REUSEADDR是让端口释放后立即就可以被再次使用。SO_REUSEADDR用于对TCP套接字处于TIME_WAIT状态下的......
  • 线程礼让
    线程礼让指让当前正在执行的线程暂停,但不阻塞。将线程从运行状态转为就绪状态。让cpu重新调度,礼让不一定成功。 //线程礼让//礼让不一定成功,看cpu心情publicclassT......
  • linux驱动移植-GPIO控制器驱动
    ----------------------------------------------------------------------------------------------------------------------------内核版本:linux5.2.8根文件系统:busybo......
  • 线程停止的方法
    使用一个标志位进行终止,当flag=false时,终止线程运行privatebooleanflag=true;@Overridepublicvoidrun(){inti=0;while(flag){......
  • linux php8.x 编译安装
    安装各种依赖yum-yinstallwgetvimpcrepcre-developensslopenssl-devellibicu-develgccgcc-c++autoconflibjpeglibjpeg-devellibpnglibpng-develfreetype......
  • C++11/std::atomic - 原子变量(不加锁实现线程互斥)
     文章目录1原子操作2C++11原子变量3使用原子变量3.1没有使用线程互斥的数据操作3.2使用互斥量保证线程互斥3.3使用原子量std::atomic保证数据互斥......
  • Linux中安装JDK
    JDK安装使用步骤1.切换到JDK目录[root@8xp3kwxbmp90uvt4JDK]#cd/root/02InstallStorage/JDK/newest2.解压压缩文件到指定文件夹[root@8xp3kwxbmp90uvt4newest]#tar-xv......
  • Linux中安装JDK
    JDK安装使用步骤1.切换到JDK目录[root@8xp3kwxbmp90uvt4JDK]#cd/root/02InstallStorage/JDK/newest2.解压压缩文件到指定文件夹[root@8xp3kwxbmp90uvt4newest]#tar-xv......
  • Linux中安装JDK
    JDK安装使用步骤1.切换到JDK目录[root@8xp3kwxbmp90uvt4JDK]#cd/root/02InstallStorage/JDK/newest2.解压压缩文件到指定文件夹[root@8xp3kwxbmp90uvt4newest]#tar......
  • Linux中安装JDK
    JDK安装使用步骤1.切换到JDK目录[root@8xp3kwxbmp90uvt4JDK]#cd/root/02InstallStorage/JDK/newest2.解压压缩文件到指定文件夹[root@8xp3kwxbmp90uvt4newest]#tar......