1. 程式人生 > >循序漸進學unix——上機記錄(四)

循序漸進學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");
}