日期:2014-05-16 浏览次数:20948 次
一连4周,每周两门考试,好长时间没能继续把上机记录完成。现在总算进入圣诞假期,争取把这一系列写完。
上回说到使用pipe在两个进程之间做双重重定向,下面我们继续看下一练习:
5,一个管道“pipe”,能否被多个进程同时访问?为了回答这一问题,创建一个父进程和两个子进程,两个子进程同时向管道写入,父进程负责读取。这一问题没有太大难度,代码如下:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void main(int argc, char** argv)
{
	char a = 'a';
	char b = 'b';
	char rcv;
	int tube[2];
	pipe(tube);
	if(fork()==0) {
		//Section fils
		printf("Fils1 : write 'a' au tube.\n");
		write(tube[1], &a, 1);
		exit(0);
	} else {
		//pere
		if(fork()==0){		
			printf("Fils2 : write 'b' au tube.\n");
			write(tube[1], &b, 1);
			exit(0);
		}
		read( tube[0], &rcv, 1);
		printf("Père : read du tube :%c. \n", rcv);
		read( tube[0], &rcv, 1);
		printf("Père : read du tube :%c. \n", rcv);
	}
}
即fcntl(pipe[0], F_SETFL, O_NONBLOCK);
完整代码:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void main(int argc, char** argv)
{
	char a = 'a';
	char b = 'b';
	char rcv;
	int tube[2];
	int tube1[2];
	pipe(tube);
	pipe(tube1);
	fcntl(tube[0], F_SETFL, O_NONBLOCK);
	fcntl(tube1[0], F_SETFL, O_NONBLOCK);
	if(fork()==0) {
		//Section fils
		printf("Fils1 : write 'a' au tube.\n");
		write(tube[1], &a, 1);
		sleep(1);
		printf("Fils1 : write 'c' au tube.\n");
		a='c';
		write(tube[1], &a, 1);
		exit(0);
	} else {
		//pere
		if(fork()==0){		
			sleep(5);
			printf("Fils2 : write 'b' au tube1.\n");
			write(tube1[1], &b, 1);
			exit(0);
		}
		while(1)
		{
			if(read( tube[0], &rcv, 1)!=-1)
				printf("Père : read du tube :%c. \n", rcv);
			if(read( tube1[0], &rcv, 1)!=-1)
				printf("Père : read du tube1 :%c. \n", rcv);
		}
	}
}
之前的pipe只能在程序中创建,用于同一程序的进程间通信,而 Named pipe是一个文件形式的pipe,通过mkfifo命令或同名函数创建,可以在磁盘上看到。它可以用来在不同的程序间传递信息。
先在命令行中使用mkfifo命令创建一个名为pipenomme的pipe文件后,就可以像往常一样使用了,不过这次通信的是两个程序:
读:
#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
void main()
{
	
	char str[50];
	int fd = open("pipenomme", O_RDONLY);
	if(fd==-1)return;
	else printf("Open pipe nommée pour la lecture\n");
	close(0);
	dup(fd);
	scanf("%s",str);
	printf("J'ai re?u %s\n", str);
}
#include<unistd.h>
#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
void main()
{
	char str[50];
	int fd = open("pipenomme", O_WRONLY);
	if(fd==-1)return;
	else printf("Open pipe nommée pour l'ecriture\n");
	close(1);
	dup(fd);
	//scanf("%s",str);
	printf("Ce_msg_est_envoyé_par_7_WR_:)\n");
}