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);
				
	}
}


实现了多进程并发。

 

 

 

 

 

 

微信扫码订阅
UP更新不错过~
关注
  • 0
    点赞
  • 17
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

yff1030

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值