Linux 進程創建及多進程

說到進程,首先要明確的一個概念就是什麼是進程,進程是“a program in execution”。一個進程由如下元素組成:

–程序的上下文(context),它是程序當前執行的狀態

–程序的當前執行目錄

–程序訪問的文件和目錄

–程序的信任狀態或者說訪問權限,比特它的文件模式和所有權

–內存和其他分配給進程的系統資源

本文討論創建進程

最近本人寫了一個關於進程操作的程序,之前對進程有過了解,但是,沒有寫程序,所以總感覺是徘徊在門外,很多東西只是瞭解個大概,在這次真的要寫程序的時候,不知道如何下手。

1、  system函數

在頭文件#include<stdlib.h>中包含

函數原型: int system(const char *command);

功能描述:  system()通過調用/bin/sh –c  command來執行具體的command命令,在command完成後返回。在command執行期間,SIGCHLD信號被阻塞,SIGINTSIGQUIT將被忽略。

返回值:    如果沒有找到/bin/shsystem返回127

                            如果出現其他錯誤則返回-1

                            如果執行成功則返回command的代碼。

                            但是如果commandNULLsystem返回一個非0值,否則返回0

示例:

 

2、  fork系統調用

fork調用創建一個新的進程。新的進程或者說子進程是調用進程的或者說父進程的副本。

Fork的語法是

#include<unistd.h>

pid_t fork(void);

如果fork執行成功,就向父進程返回子進程的PID,並向子進程返回0。這就一起這即使你只調用fork一次,他也會返回兩次。

Fork創建的新進程是和父進程(除了PIDPPID)一樣的副本,包括真實和有效的UIDGID、進程組合會話ID、環境、資源限制、打開的文件以及共享內存段。

父進程和子進程之間有一點區別。子進程沒有繼承父進程的超市設置(使用alarm調用

)父進程創建的文件鎖,或者未決信號。要理解的關鍵概念是fork創建的新進程是父進程的一個準確副本。

 

2fork系統調用

fork調用創建一個新的進程。新的進程或者說子進程是調用進程的或者說父進程的副本。

Fork的語法是

#include<unistd.h>

pid_t fork(void);

如果fork執行成功,就向父進程返回子進程的PID,並向子進程返回0。這就一起這即使你只調用fork一次,他也會返回兩次。

Fork創建的新進程是和父進程(除了PIDPPID)一樣的副本,包括真實和有效的UIDGID、進程組合會話ID、環境、資源限制、打開的文件以及共享內存段。

父進程和子進程之間有一點區別。子進程沒有繼承父進程的超市設置(使用alarm調用)父進程創建的文件鎖,或者未決信號。要理解的關鍵概念是fork創建的新進程是父進程的一個準確副本。

示例:

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
	pid_t child;
	if((child = fork()) == -1)
	{
		perror("fork");
		exit(EXIT_FAILURE);
	}
	else if(child == 0)					//子進程中
	{
		puts("in child");
		printf("\tchild pid = %d\n",getpid());
		printf("\tchild ppid = %d\n",getppid());
		exit(EXIT_SUCCESS);
	}
	else	
	{
		puts("in parent");
		printf("\tparent pid = %d\n",getpid());
		printf("\tparent ppid = %d\n",getppid());
	}
	exit(EXIT_SUCCESS);
}


 

3、  exec函數族

fork函數一樣,exec也在<unistd.h>中聲明。它的原型爲:

int execl(const char *path, const char*arg, ...);

int execlp(const char *file, const char*arg, ...);

int execle(const char *path, const char*arg , ..., char * const envp[]);

int execv(const char *path, char *constargv[]);

int execvp(const char *file, char *constargv[]);

int execve(const char *path, char *constargv[], char *const envp[]);

 

exec用被執行的程序完全替換了調用進程的映像。Fork創建了一個新進程就產生了一個新的PIDexec啓動一個新程序,替換原有進程。因此被執行的進程的PID不會改變。

例如:

int execve(const char *path, char *constargv[], char *const envp[]);

接收三個參數:

path是要執行的二進制文件或腳本的完整路徑。

argv是要傳遞給程序的完整參數列表,包括argv[0],它一般是執行程序的名字,

envp是指向用於執行execed程序的專門環境的指針。

 

這幾個函數可以簡單討論如下:

名字中含有l的函數:希望接受以逗號分隔的參數列表,列表以NULL指針作爲結束標誌,這些參數將傳遞給被執行的程序。

名字中包v的函數:則接受一個向量,也就是以空結尾的字符串的指針數組。這個數組必須以一個NULL指針作爲結束標誌。

不過,需要注意的是,有時候可能那個NULL,需要寫成(char *)0

 

//一個創建num個進程的示例:
//其中batchscript是已經寫好的shell腳本文件。
void createsubprocess(int num)
{
	int i;
	int child;
	int pid[num];	
	for(i=0;i<num;i++)
	{
		if((child = fork()) == -1)
		{
			perror("fork");
			exit(EXIT_FAILURE);
		}
		else if(child==0)		//子進程運行
		{
			pid[i]=getpid();
			if(execl("/usr/audio/./batchscript","./batchscript",(char *)0) == -1 )
			{
				perror("execl");
				exit(EXIT_FAILURE);
			}
		}
		
		else
		{	
		}   
	}
	for(i=0;i<num;i++)
	{
		waitpid(pid[i],NULL,0);
				
	}
}


實現了多進程併發。

 

 

 

 

 

 

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