一、如何創建進程?
linux通過fork()系統調用創建新一個進程,老進程叫父進程,複製生成的新進程叫子進程。父子關係是相對的,每一代都有一個父子關係。
fork函數定義如下:
#include <unistd.h>
pid_t fork(void);
實例1:
#include <unistd.h>
#include <stdio.h>
int main (void)
{
pid_t fpid = -1; //fpid表示fork函數返回的值
printf("this is fork test.\r\n");
fpid=fork();
if (fpid < 0)
printf("error in fork!\r\n");
if (fpid == 0) //子進程
{
printf("\r\n");
printf("fpid is %d\r\n",fpid);
printf("child process, my PID is %d\r\n",getpid());
printf("child process, my PPID is %d\r\n",getppid());
}
if (fpid > 0) //父進程
{
printf("\r\n");
printf("fpid is %d\r\n",fpid);
printf("parent process, my PID is %d\r\n",getpid());
printf("parent process, my PPID is %d\r\n",getppid());
}
printf("hello world, pid = %d.\r\n", getpid());
return 0;
}
解釋:
(1)fork函數調用一次會返回2次,返回值等於0的就是子進程,而返回值大於0的就是父進程。
(2)p1 = fork()以後的代碼會運行兩次,一次是父進程運行的,一分是子進程運行的,誰先運行不一定,由操作系統調度器說了算。
(3)fork的返回值在子進程中等於0,在父進程中等於本次fork創建的子進程的進程ID。
二、父子進程對文件的操作
1.子進程繼承父進程中打開的文件
父進程以O_TRUNC的方式打開文件,後續和子進程對文件進行寫入
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
// 首先打開一個文件
int fd = -1;
pid_t pid = -1;
fd = open("1.txt", O_RDWR | O_TRUNC);
if (fd < 0)
{
perror("open");
return -1;
}
// fork創建子進程
pid = fork();
if (pid > 0)
{
// 父進程中
printf("parent.\r\n");
write(fd, "hello", 5);
Sleep(1);//給系統調度充足的時間
}
else if (pid == 0)
{
// 子進程
printf("child.\r\n");
write(fd, "world", 5);
Sleep(1);//給系統調度充足的時間
}
else
{
perror("fork");
exit(-1);
}
close(fd);
return 0;
}
2、父子進程各自獨立打開同一文件實現共享
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
// 首先打開一個文件
int fd = -1;
pid_t pid = -1;
// fork創建子進程
pid = fork();
if (pid > 0)
{
// 父進程中
fd = open("1.txt", O_RDWR );
if (fd < 0)
{
perror("open");
return -1;
}
printf("parent.\n");
write(fd, "hello", 5);
sleep(1);
}
else if (pid == 0)
{
// 子進程
fd = open("1.txt", O_RDWR );
if (fd < 0)
{
perror("open");
return -1;
}
printf("child.\n");
write(fd, "world", 5);
sleep(1);
}
else
{
perror("fork");
exit(-1);
}
close(fd);
return 0;
}
結果都是world,原因如下表,父子進程文件描述符所指向的文件表是獨立的。當父進程先執行的時候,寫入了hello,子進程執行的時候,由於文件表獨立,所以文件指針也獨立,子進程是從0偏移地址寫,所以會將之前寫的hello覆蓋掉,只剩下world。
要想實現接續寫的效果,只需在open時使用O_APPEND
原因:如果用O_APPEND標誌打開一個文件,則相應標誌也被設置到文件表項的文件狀態標誌中. 每次對這種具有追加寫標誌的文件執行寫操作時,文件表項中的當前文件偏移量首先會被設置爲i節點表項中的文件長度,這就使得每次寫入的數據都追加到文件的當前尾端處.