进程fork

进程简介

linux是一个多任务操作系统,这也是与单片机最大的区别,它可以运行多个程序,每个程序都是一个进程,当然一个程序也可能包含多个进程。不同用户在同一操作系统运行的同一个进程,共享一个函数库与程序代码。

在终端输入ps -ef 命令,可查看所有运行的进程

每个进程都有唯一的PID,可以看到PID为1的特殊进程叫做init进程,负责管理其他进程。

进程调度

创建进程fork,vfork

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);
pid_t vfork(void);

fork()调用失败返回-1,调用成功则父进程的fork调用返回子进程的PID,子进程fork调用返回0。

fork与vfork区别在于 :

1、fork子进程拷贝了父进程数据段,堆,栈。而vfork子进程共享父进程数据段,堆,栈。

2、vfork子进程先运行,fork子进程父进程执行顺序不定

创建fork.c文件,内容如下

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int global=1;

int main()
{
	int v = 0; 
	switch(fork())
	{
		case -1://创建 失败
			return -1;
		case 0://子进程
			global=100;//子进程改变全局变量的值
			v--;       //子进程改变局部变量的值
			printf("child pid:%d, g_value:%d, value:%d\n", getpid(), global, v);
			exit(0);
		    break;
		default://父进程
			sleep(1);
			printf("parent pid:%d g_value:%d, value:%d\n", getpid(), global, v);
	    	break;
	}
	return 0;
}

vfork.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int global=1;

int main()
{
	int v = 0; 
	switch(vfork())
	{
		case -1://创建 失败
			return -1;
		case 0://子进程
		
			global = 100;
			v--;
			printf("child pid:%d,g_value:%d,value:%d\n", getpid(), global, v);
			exit(0);
		    break;
		default://父进程
//			sleep(1);
			printf("parent pid:%d g_value:%d,value:%d\n", getpid(), global, v);
		    break;
	}
	return 0;
}

子进程改变了全局变量和局部变量,父进程中也跟着改变了

 

进程同步

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *stat_loc);

当子进程执行时,wait()可以暂停父进程的执行,使其等待。一旦子进程执行完,等待的父进程就会重新执行。如果有多个子进程在执行,那么父进程中的wait()在第一个子进程结束时返回,恢复父进程执行。

exec 系列调用

当exec 调用成功,调用进程将被覆盖,然后从新程序的入口开始执行。这样就产生了一个新的进程取代了原来的进程,但是它的进程标识符与调用进程相同(PID不变)。

#include <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 *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);

例子 建立execl.c内容是:

#include <error.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
	if(execl("/mnt/hgfs/share_2019/linux_c/execl/helloexecl", "helloexecl", "123", "abc", NULL) < 0)
	{
		perror("execl error\n");
		return -1;
	}
	return 0;
}

创建另一c文件 helloexecl.c,打印所有命令行参数。

#include<stdio.h>

int main(int argc,char *argv[])
{
	int i = 0;
	printf("argc = %d\n", argc);
	for(; i < argc; i++)
	{
		printf("argv[%d] = %s\n", i, argv[i]);
	}
	return 0;
}

输入命令gcc  execl.c 与gcc -o helloexecl helloexecl.c

执行a.out可执行文件

终止进程

#include <unistd.h>

void exit(int status);

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值