函数fork vfork
生活随笔
收集整理的這篇文章主要介紹了
函数fork vfork
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、函數(shù)fork
fork函數(shù)原型:
#include <unistd.h> pid_t fork(void);?
二、程序清單
1. 測試代碼:
#include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <fcntl.h> #include <iostream> using namespace std;static int global_val = 0; int main() {int *p = (int*)malloc(sizeof(int));*p = 0;int m = 2;pid_t pid;int fd = open("mytest", O_RDWR | O_CREAT, 0666);if ((pid = fork()) < 0){cout << "fork error" << endl;}else {if (pid == 0){char buf[20] = "\0";int res = read(fd, buf, 20);cout << "pid is " << getpid() << " res is " << res << " fd is " << fd << " buf is " << buf << endl;close(fd);//sleep(1);char bufs[8] = "shenlei";lseek(fd, 0, SEEK_SET);write(fd, bufs, strlen(bufs));global_val++;m++;(*p)++;}else {sleep(1);char buf[20] = "\0";lseek(fd, 0, SEEK_SET);int res = read(fd, buf, 20);cout << "pid is " << getpid() << " res is " << res << " fd is " << fd << " buf is " << buf << endl;cout << *p << " " << m << " " << global_val << endl;}}return 0; } #include <stdio.h> #include <unistd.h>int main() {pid_t pid;for(int i = 0; i < 4; ++i)printf("--------i = %d\n", i);pid = fork();if(pid > 0) printf("parent process, pid = %d\n", getpid());else if(pid == 0)printf("child process, pid = %d, ppid = %d\n", getpid(), getppid());for(int i = 0; i < 4; ++i)printf("i = %d\n", i);return 0; }輸出結(jié)果:
?
2. 測試代碼:
#include <stdio.h> #include <unistd.h>int counter = 200; int main() {int number = 5;int i;pid_t pid;for(i = 0; i < number; ++i) {pid = fork();if(pid == 0) {break;}}if(i == 0){counter += 200;printf("first process, pid = %d\n", getpid());printf("-----couner = %d\n", counter);}if(i == 1){counter += 200;printf("second process, pid = %d\n", getpid());printf("-----couner = %d\n", counter);}if(i == 2){counter += 200;printf("thrid process, pid = %d\n", getpid());printf("-----couner = %d\n", counter);}if(i == number){sleep(3);counter += 400;printf("parent process, pid = %d\n", getpid());printf("-----couner = %d\n", counter);}return 0; }輸出結(jié)果:
3. 測試代碼:
#include <unistd.h> #include <stdlib.h> #include <stdio.h>int main() {int i;pid_t pid;printf("xxxxxxxxxxxxxxxxxxxxx\n");for(i = 0; i < 5; ++i) {pid = fork();if(pid == -1) {perror("fork error:");exit(1);} else if(pid == 0) {break;}}if(i < 5) {sleep(i);printf("I'am %d child, pid = %d\n", i+1, getpid());} else {sleep(i);printf("I'am parent\n");}return 0; }輸出結(jié)果:
?
三、父子進程共享
父子進程之間在fork后,有哪些相同,有哪些相異之處呢?
剛fork之后:
父子相同處:全局變量、.data、.text、棧、堆、環(huán)境變量、用戶ID、宿主ID(家目錄)、進程工作目錄、信號處理方式
父子不同處:進程ID、fork返回值、父進程ID、進程運行時間、鬧鐘(定時器)、未決信號集
似乎,子進程復(fù)制了父進程0-3G用戶空間內(nèi)容,以及父進程的PCB、但pid不同,真的每fork一個進程都要將父進程完全程的0-3G地址空間完全拷貝一份,然后在映射至物理內(nèi)存嗎?
當(dāng)然不是!父子進程間遵循讀時共享寫時復(fù)制的原則,這樣設(shè)計,無論子進程執(zhí)行父進程的邏輯還是執(zhí)行自己的邏輯都能節(jié)省內(nèi)存開銷。
重點注意:躲避父子進程共享全局變量的知識誤區(qū)!
【重點】:父子進程共享:1. 文件描述符(打開文件的結(jié)構(gòu)體)? 2. mmap建立的映射區(qū)
?
1. 測試代碼:
#include <unistd.h> #include <stdlib.h> #include <stdio.h>int var = 24;int main() {pid_t pid;pid = fork();if(pid == -1) {perror("fork");exit(1);} else if(pid > 0) {var = 55;sleep(1);printf("I'am parent pid = %d, parent ID = %d, var = %d\n", getpid(), getppid(), var);} else if(pid == 0) {var = 100;printf("child pid = %d, parent ID = %d, var = %d\n", getpid(), getppid(), var);}printf(" var = %d\n", var); return 0; }輸出結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的函数fork vfork的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 曙光女神打不详之刃求攻略
- 下一篇: 函数exec