循序漸進學unix——上機記錄(四)
阿新 • • 發佈:2019-01-11
一連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");
}