fork mmap 共享映射区

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);

fork 调用失败则返回-1


//fork 创建一个子进程
#include <stdio.h>
#include <unistd.h>

int main(void)
{
	pid_t pid;

	pid = fork();

	if(pid == 0){
		printf("child\n");
	} else {
		printf("parent\n");
	}

	return 0;
}

/*
$ ./fork
parent
child
*/<pre name="code" class="cpp">












/*
creat parent child
*/

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

int main(void)
{
	pid_t pid;
	char *message;
	int n;

	pid = fork();
	if(pid == -1){
		perror("fork error");
		exit(1);
	}else if(pid == 0){
		printf("i'am child, pid = %d\n", getpid());
		printf("parent id = %d\n", getppid());

	}else if(pid > 0){
		printf("parent, pid = %d\n", getpid());
	}

	return 0;

}

/*akaedu@akaedu-G41MT-D3:~/lin/20140828_fock$ ./4
parent, pid = 7034
i'am child, pid = 7035
parent id = 7034
*/


<pre name="code" class="cpp">/*
creat 5 child
循环创建5个子进程
*/

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

int main(int argc, char *argv[])
{
	int n = 5, i;			   //默认创建5个子进程

	if(argc == 2){
		n = atoi(argv[1]);
	}

	for(i = 0; i < n; i++){  	   //出口1,父进程专用出口
		if(fork() == 0)	   	
			break;  	   //出口2,子进程出口,i不自增
	}

	if(n == i){
		sleep(i);
		printf("parent. pid = %d\n", getpid());
	}else {
		sleep(i);
		printf("%d child. pid = %d\n", i+1, getpid());
	}

	return 0;

}

/*akaedu@akaedu-G41MT-D3:~/lin/20140828_fock$ ./6
1 child. pid = 7448
2 child. pid = 7449
3 child. pid = 7450
4 child. pid = 7451
5 child. pid = 7452
parent. pid = 7447
*/


//父子进程共享打开的文件,建立的映射区
//不共享:.data malloc stack heap 命令行参数 全局变量 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int a = 100;

int main(void)
{
	pid_t pid;
	pid = fork();

	if(pid == 0){	//sun
		a = 2000;	//子进程修改了a值,父进程不共享修改
		printf("child, a = %d\n", a);
	} else {
		sleep(1);	//保证sun先运行
		printf("parent, a = %d\n", a);
	}

	return 0;
}

/*
akaedu@akaedu-G41MT-D3:~/桌面/T74_system/0828_chp3_process_environ_control$ ./fork_shared 
child, a = 2000
parent, a = 100
*/













/****推荐****/
/*
父子进程映射区共享

/dev/zero 是一个特殊的文件,当你读它的时候,它会提供无限的空字符(NULL, ASCII NUL, 0x00)。
其中的一个典型用法是用它提供的字符流来覆盖信息,另一个常见用法是产生一个特定大小的空白文件。
BSD就是通过mmap把/dev/zero映射到虚地址空间实现共享内存的。

*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define N 4

int main(void)
{
	int *p;
	pid_t pid;

	int fd = open("/dev/zero", O_RDWR); 

	p = mmap(NULL, N, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if(p == MAP_FAILED){		//注意:不是p == NULL
		perror("mmap error");
		exit(1);
	}
	close(fd);   		//映射完就可以关闭fd

	pid = fork();				//创建子进程
	if(pid == 0){
		*p = 2000;
		printf("child, *p = %d\n", *p);
	} else {
		sleep(1);
		printf("parent, *p = %d\n", *p);
	}

	munmap(p, N);				//释放映射区

	return 0;
}

/*akaedu@akaedu-G41MT-D3:~/桌面/T74_system/0828_chp3_process_environ_control$ ./fork_map_anon 
child, *p = 2000
parent, *p = 2000
*/
<pre name="code" class="cpp">



//父子进程共享打开的文件,建立的映射区 
//方法较老,不推荐
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

int var = 100;

int main(void)
{
	int *p;
	pid_t pid;

	int fd;
	fd = open("temp", O_RDWR|O_CREAT|O_TRUNC, 0644);
	if(fd < 0){
		perror("open error");
		exit(1);
	}
	unlink("temp");				//删除临时文件目录项

	lseek(fd, 3, SEEK_SET);		//open的文件长度0,不能直接建映射区
	write(fd, "a", 1);			//引起IO操作,物理上拓展文件

	p = (int *)mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
	if(p == MAP_FAILED){		//注意:不是p == NULL
		perror("mmap error");
		exit(1);
	}
	close(fd);					//映射区建立完毕,即可关闭文件

	pid = fork();				//创建子进程
	if(pid == 0){
		*p = 2000;
		var = 1000;
		printf("child, *p = %d, var = %d\n", *p, var);
	} else {
		sleep(1);
		printf("parent, *p = %d, var = %d\n", *p, var);
	}

	munmap(p, 4);				//释放映射区

	return 0;
}

/*akaedu@akaedu-G41MT-D3:~/桌面/T74_system/0828_chp3_process_environ_control$ ./fork_mmap 
child, *p = 2000, var = 1000
parent, *p = 1627389952, var = 100
*/

 

 
 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值