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