日期:2014-05-16  浏览次数:20770 次

循序渐进学unix——上机记录(四)

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

6,不阻塞的pipe。创建一个进程同时从两个pipe中读取信息,为了能够立即显示某一管道中读取的信息而不被另一管道阻塞,可以使用函数fcntl(). 这一函数可以实现对文件描述符的很多操作,如设置标志位等等。在这一问题中,我们需要使用这一函数把pipe的读入段设为不阻塞。

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

7.使用“命名管道”。“named pipe”。

之前的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");
}