linux進程(二)——如何創建進程?

一、如何創建進程?

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節點表項中的文件長度,這就使得每次寫入的數據都追加到文件的當前尾端處.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章