文章目录
BEGINDemo 1 - 了解fork执行方式code & resultcomprehension Demo 2 - fork的返回值研究code & resultcomprehension Demo 3 - lockf锁和并发code & resultcomprehension Demo 4 - 控制fork创建顺序code & resultcomprehension ENDBEGIN
Demo 1 - 了解fork执行方式
code & result
#include <cstdio>#include <iostream>#include <unistd.h>using namespace std;int main ( void ) {fork();fork();fork();cout << "S" << endl;return 0;}
comprehension
执行第一个fork调用时,
进程A创建了进程B;
执行第二个fork调用时,
进程A创建了进程C,
进程B创建了进程D;
执行第三个fork调用时,
进程A创建了进程E,
进程B创建了进程F,
进程C创建了进程G,
进程D创建了进程H。
如图,
Demo 2 - fork的返回值研究
code & result
#include <iostream>#include <unistd.h>using namespace std;int main ( void ) {cout << "Program begin." << endl;int pid = fork();if ( pid != 0 ) {cout << "Process 'pid != 0' -> true (parentId, selfId):" <<"(" << getppid() << ", " << getpid() << ")" <<" / pid=" << pid << endl;for ( int i = 0; i < 10; ++i ) {cout << "Parent " << "\t" << i << endl;sleep(1);}} else {cout << "Process 'pid != 0' -> false (parentId, selfId):" <<"(" << getppid() << ", " << getpid() << ")" <<" / pid=" << pid << endl;for ( int i = 0; i < 10; ++i ) {cout << "Child " << "\t\t" << i << endl;sleep(1);}}cout << "Program end." << endl;return 0;}
comprehension
也就是可以理解为, 当执行 fork() 之后, 产生的子进程是从当前fork()函数调用的位置开始继续执行.
并且, fork() 是返回两个值的, 一个给自己, 一个给子进程. 也正是如此, if else 才能都输出.
Demo 3 - lockf锁和并发
code & result
#include <iostream>#include<unistd.h>using namespace std;/* lockf(files,function,size),* file 文件描述符: 1表示stdout标准输出;* function 锁定和解锁: 1表示锁定, 0表示解锁;* size 锁定或者解锁的字节数: 为0, 表示从文件的当前位置到文件尾.*/int main() {cout << "Program begin." << endl;int p1, p2,i;while( ( p1=fork() ) == -1 ); // main create processif( p1 != 0 ) {// ***main self***cout << endl <<"Process 'p1 != 0' -> true" << " / p1=" << p1 <<" (parentId, selfId):" << "(" << getppid() << ", " << getpid() << ")" <<"\t(main self when 1st process created.)" << endl;cout << endl;while( ( p2 = fork() ) == -1 ); // main create processif ( p2 != 0 ) {// ***main self***lockf( 1, 1, 0 ); // lockcout << "Process 'p2 != 0' -> true" << " / p2=" << p2 <<" (parentId, selfId):" << "(" << getppid() << ", " << getpid() << ")" <<"\t(main self when 2st process created)" << endl;for ( i = 0 ; i < 5 ; ++i ) cout << "A: " << "\t\t" << i << endl;lockf( 1, 0, 0 ); // unlock} else {// main's 2th sub processlockf( 1, 1, 0 ); // lockcout << "Process 'p2 != 0' -> false" << " / p2=" << p2 <<" (parentId, selfId):" << "(" << getppid() << ", " << getpid() << ")" <<"\t(main's 2th sub process)" << endl;for ( i = 0 ; i < 5 ; ++i ) cout << "C: " << "\t\t" << i << endl;lockf( 1, 0, 0 ); // unlock}}else {// main's 1th sub processlockf( 1, 1, 0 ); // 加锁cout << "Process 'p1 != 0' -> false" << " / p1=" << p1 <<" (parentId, selfId):" << "(" << getppid() << ", " << getpid() << ")" <<"\t(main's 1th sub process)" << endl;for ( i = 0 ; i < 5 ; ++i ) cout << "B: " << "\t\t" << i << endl;lockf( 1, 0, 0 ); // 解锁}cout << "Program end." << endl;return 0;}
comprehension
进程创建之后是并发执行的.
如图所示, main进程创建了两次新进程,
在main进程中, p1 和 p2 分别为 子进程的 pid,
在子进程中, p1 和 p2 都为0, 这也是子进程的标记.
fork()函数有两个返回值,
返回给父进程 -> 子进程pid
返回给子进程 -> 0
也正是充分利fork()之后
父子进程皆从fork调用位置继续执行
与fork()的两个返回值
这两大性质, 才得以控制代码中进程的逻辑关系.
Demo 4 - 控制fork创建顺序
code & result
#include <iostream>#include<unistd.h>using namespace std;/* lockf(files,function,size),* file 文件描述符: 1表示stdout标准输出;* function 锁定和解锁: 1表示锁定, 0表示解锁;* size 锁定或者解锁的字节数: 为0, 表示从文件的当前位置到文件尾.*/int main() {cout << "Program begin." << endl;int p1, p2,i;while( ( p1=fork() ) == -1 ); // main create processif( p1 != 0 ) {// ***main self***lockf( 1, 1, 0 ); // 加锁cout << "Process 'p1 != 0' -> false" << " / p1=" << p1 <<" (parentId, selfId):" << "(" << getppid() << ", " << getpid() << ")" <<"\t(main's self)" << endl;for ( i = 0 ; i < 5 ; ++i ) cout << "A: " << "\t\t" << i << endl;lockf( 1, 0, 0 ); // 解锁}else {// main's 1th sub processwhile( ( p2 = fork() ) == -1 ); // main's 1th process create processif ( p2 != 0 ) {// ***main's 1th sub process self***lockf( 1, 1, 0 ); // lockcout << "Process 'p2 != 0' -> true" << " / p2=" << p2 <<" (parentId, selfId):" << "(" << getppid() << ", " << getpid() << ")" <<"\t(main's 1th sub process self when main's 1th sub process's 1th sub process created)" << endl;for ( i = 0 ; i < 5 ; ++i ) cout << "B: " << "\t\t" << i << endl;lockf( 1, 0, 0 ); // unlock} else {// main's 1th sub process's 1th sub processlockf( 1, 1, 0 ); // lockcout << "Process 'p2 != 0' -> false" << " / p2=" << p2 <<" (parentId, selfId):" << "(" << getppid() << ", " << getpid() << ")" <<"\t(main's 1th sub process's 1th sub process when main's 1th sub process's 1th sub process created)" << endl;for ( i = 0 ; i < 5 ; ++i ) cout << "C: " << "\t\t" << i << endl;lockf( 1, 0, 0 ); // unlock}}cout << "Program end." << endl;return 0;}
comprehension
对比 Demo3 理解它!
END
相信聪明的你一定明白了吧!
如果觉得《关于 Linux fork()进程创建函数 的 执行方式 返回值 lockf锁和并发 控制创建顺序 的探索》对你有帮助,请点赞、收藏,并留下你的观点哦!