溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Linux進程函數(shù)fork(),vfork(),execX()有什么用

發(fā)布時間:2021-07-14 13:39:15 來源:億速云 閱讀:98 作者:小新 欄目:服務(wù)器

這篇文章給大家分享的是有關(guān)Linux進程函數(shù)fork(),vfork(),execX()有什么用的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

函數(shù)fork()

fork函數(shù):創(chuàng)建一個新進程

1、fork()成功后,將為子進程申請PCB和用戶內(nèi)存空間。
2、子進程會復(fù)制父進程用戶空間的所有數(shù)據(jù)(代碼段、數(shù)據(jù)段、BSS、堆、棧),文件描述符。
3、復(fù)制父親進程PCB中絕大多數(shù)信息。
4、雖然子進程復(fù)制了文件描述符,而對于文件描述符相關(guān)的文件表項(struct file結(jié)構(gòu)),則采用共享的方式。

一個實例:

#include <unistd.h> //fork fuction
#include <fcntl.h> //file operator
#include <sys/types.h>
#include <stdio.h> 
#include <stdlib.h> //exit fuction
#include <string.h>
int main() {
 pid_t pid;
 int i=1; 
 int status;
 char *ch2="hello",*ch3="world",*ch4="IN";
 int fd;
 if ((fd=open("fork.txt",O_RDWR|O_CREAT,0644))==-1) {
 perror("not open");
 exit(EXIT_FAILURE);
 }
 if (write(fd,ch2,strlen(ch2))==-1) { //write in fork.txt
 perror("not write");
 exit(EXIT_FAILURE);
 }
 if ((pid=fork())==-1) {
 perror("fork error"); 
 exit(EXIT_FAILURE);
 }
 else if(pid==0) {  //son process
 int i=2;   //change i
 printf("child:i=%d\n",i);
 if (write(fd,ch3,strlen(ch3))==-1)
 perror("child write");
 return 0;
 }
 else {
 sleep(1);
 printf("parent:i=%d\n",i);
 if (write(fd,ch4,strlen(ch4))==-1)
 perror("child write");
 wait(&status);
 return 0;
 }
}

運行:

[root@localhost linux]# gcc -o fork fork.c 
[root@localhost linux]# ./fork 
child:i=2 
parent:i=1

可以看到在子進程中改變了i的值,然而父進程i仍為1,所以說子進程和父進程有自己的用戶空間。而打開所創(chuàng)建的fork.txt可以得到hellowordIN,父子進程共同對一個文件操作寫入的數(shù)據(jù)是不交叉覆蓋的,說明父子進程共享文件偏移,一次共享文件表項。

函數(shù)vfork()

與fork()函數(shù)不同,vfork()函數(shù)在創(chuàng)建進程是并不復(fù)制父進程的地址空間,而是在必要的時候才申請新的存儲空間,因此使得vfork()更有效率。

特別注意的是vfork()是共享父進程的代碼以數(shù)據(jù)段。

一個例子:

#include <unistd.h> //fork fuction
#include <fcntl.h> //file operator
#include <sys/types.h>
#include <stdio.h> 
#include <stdlib.h> //exit fuction
#include <string.h>
int i=10;
int main() {
 pid_t pid;
 if ((pid=fork())==-1) {
 perror("fork error"); 
 exit(EXIT_FAILURE);
 }
 else if(pid==0) {  //son process
 i++;
 printf("child:i=%d\n",i);
 _exit(0);  
 }
 else {
 sleep(1);
 printf("parent:i=%d\n",i);
 return 0;
 }
}

注意:上面的代碼中回收子進程用的是_exit(0),如果用return 0;的話它會回收用戶空間,因此在父進程調(diào)用的時候會出現(xiàn)段錯誤。

下面是調(diào)用輸出結(jié)果:

如果以fork()創(chuàng)建則會輸出: 
[root@localhost linux]# ./fork 
child:i=11 
parent:i=10 
如果改為vfork(),則: 
child:i=11 
parent:i=11

函數(shù)exec X()系列函數(shù)

用fork()函數(shù)創(chuàng)建紫禁城后,如果希望在當(dāng)前子進程中運行新的程序,則可以調(diào)用execX系列函數(shù)。
注意:當(dāng)進程調(diào)用exec函數(shù)后,該進程的用戶空間資源完全有新程序代替。
這些函數(shù)的區(qū)別在于:

1、指示新程序的位置是路徑還是文件名
2、在使用參數(shù)時是使用參數(shù)列表哈市使用argv[]數(shù)組
3、后綴有l(wèi)(list)表示使用參數(shù)列表,v表示使用argv[]數(shù)組

具體如下所示:

#include<unistd.h>

int execl(const char *pathname,const char *arg0,.../*(char *) 0 */);
int execv(const char *pathname,char *const argv[]);
int execle(const char *pathname,const char *arg0,.../*(char *) 0
 ,char *const envp[] */);
int execve(const char *pathname,char *const argv[],char *const envp[]);
int execlp(const char *filename,const char*arg0,.../*(char *) 0*/);
int execvp(const char *filename, char *const argv[]);
int fexecve(int fd,char *const argv[],char *const evnp[]);

一個實例:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc ,char* argv[]) {
 pid_t pid;
 if ((pid=fork())==-1)
 printf("error");
 else if (pid==0) 
 execl("/bin/ls","ls","-l",argv[1],(char *)0);
 else
 printf("father ok\n");
}

運行可以看到在子進程中執(zhí)行了ls命令。

[yqtao@localhost linux]$ gcc -o exec execX.c
[yqtao@localhost linux]$ ./exec /home father ok

//execlp()函數(shù)使用

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc ,char* argv[]) {
 execlp("ls","ls","-l","/home",(char*)0);
}

//execv()函數(shù)的使用

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc ,char* argv[]) {
 char* argv1[]={"ls","-l","/home",0};
 execv("/bin/ls",argv1);
}

ecvp()會從環(huán)境變量PATH所指定的目錄中查找文件名作為第一個參數(shù),第二個及以后的參數(shù)由參數(shù)列表,注意最后一個成員必須為NULL

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc ,char* argv[]) {
 char* argv1[]={"ls","-l","/home",0};
 execvp("ls",argv1);
}

感謝各位的閱讀!關(guān)于“Linux進程函數(shù)fork(),vfork(),execX()有什么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI