操作系統實驗二
fork函數
作用
fork函數將運行着的程序分成2個(幾乎)完全一樣的進程,每個進程都啟動一個從代碼的同一位置開始執行的線程
返回值
- 負值:創建子進程失敗。
- 零:返回到新創建的子進程。
- 正值:返回父進程或調用者。該值包含新創建的子進程的進程ID

用法
pid_t pid=fork();如果創建成功,會有兩個進程:父進程和子進程,fork在這兩個進程中分別返回,就是返回兩次且返回值不同。
一段程序
# include<stdio.h>
# include<sys/types.h>
# include<unistd.h>
int main()
{
int pid1, pid2;
printf("I am father %d! My father is %d.\n", getpid(), getppid());
if ((pid1 = fork())<0) //fork return value < 0 , create failed
{
printf("Child1 fail create!\n");
return 1;
}
else if (pid1 == 0) //fork return value = 0, son is running
{
printf("I am son %d! My father is %d. \n", getpid(), getppid());
return 0;
}
if ((pid2 = fork())<0)
{
printf("Child2 fail create!\n");
return 0;
}
else if (pid2 == 0)
{
printf("I am daughter %d! My father is %d.\n", getpid(), getppid());
return 0;
}
}
編譯運行
gcc fork.c -o fork
./fork
運行結果

分析: 首先是父進程,打印了它的身份和進程號,還有它的父進程號
在第一個if語句中創建了子進程,子進程創建成功,返回值是0,執行第一個else if,打印身份是子進程和它的進程號和父進程號。
父進程的fork返回值是子進程號大於0,不滿足第一個條件,順序往下執行,在第二個if里創建了一個進程。
子進程創建成功,返回值是0,執行else if,打印身份、進程號和父進程號。
daughter進程的父進程號時884,是因為父進程已經運行結束了,daughter進程找不到原來的父進程,變成了孤兒進程,被其他進程收養了。

分析: 有時daughter進程和son進程順序不一樣是因為父進程比son進程執行的快,先創建了daughter進程,daughter進程先進行了打印。
打印在命令行上的原因:
處理父進程、son進程、daughter進程,還有一個shell進程,shell進程就是用戶和linux交互的進程,用於解析輸入的命令行。這四個進程都要搶占屏幕這個資源,如果被shell先搶占了,就會出現命令行,其他進程輸出就會在命令行上了。(不知道理解的對不對。。。)
孤兒進程
父進程運行結束后,它創建的子進程還在運行,這些子進程就會成為孤兒進程。
避免出現孤兒進程: 在父進程運行最后加上sleep(1),父進程不會運行那么快,保證子進程先退出。

lockf函數
參考:https://blog.csdn.net/qq_24421591/article/details/49104455
用處
實現資源的互斥訪問
例子
# include<stdio.h>
# include<sys/types.h>
# include<unistd.h>
int main(){
int pid1, pid2;
pid1=fork();
if(pid1 == 0)
{
for(int i = 0; i < 5; i ++ )
{
lockf(1,1,0); //加鎖
printf("I am son %d\n",i);
lockf(1,0,0); //解鎖
sleep(3); //等待3s
}
}
else
{
pid2=fork();
if(pid2 == 0)
{
for(int i = 0; i < 5; i ++ )
{
lockf(1,1,0);
printf("I am daughter %d\n",i);
lockf(1,0,0);
sleep(3);
}
}
else
{
printf("I am father\n");
}
}
return 0;
}

分析: 臨界資源是屏幕,son進程和daughter進程會交替打印,是因為在循環中打印過后,會等待3s,在等待的時間里,另一個進程就是搶占資源,進行打印。
對比
將sleep(1)放在解鎖之前,這樣即使進程在sleep,其他進程也沒有機會搶占資源。

