Linux進(jìn)程之間有時需要互相傳送消息,Linux為此提供了幾種方法,其中之一就是管道。
管道
和日常生活中的一樣,管道是單向的,只是里面流動著的是數(shù)據(jù)。
匿名管道
匿名管道適用于有親緣關(guān)系的進(jìn)程,從管道的構(gòu)建形式就能夠看出來,可以在Linux shell中鍵入man 2 pipe來看一下pipe這個系統(tǒng)調(diào)用的說明,其函數(shù)原型為
int pipe(int pipefd[2]);
從這個這個函數(shù)原型可以看出,一次調(diào)用創(chuàng)建了2個fd,分別是管道的兩端,當(dāng)前進(jìn)程拿其中一端,另一端就很難給一個不相干的進(jìn)程了,一般就是給fork出來的一個進(jìn)程,也就是一個有親緣關(guān)系的進(jìn)程。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char **argv)
{
int fd[2];
int n;
pid_t pid;
char line[80];
pipe(fd);
pid = fork();
if(pid > 0){
close(fd[0]);
sleep(1);
printf("%d\n", __LINE__);//17
write(fd[1], "hello world\n", 13);
printf("%d\n", __LINE__);//19
sleep(1);
printf("%d\n", __LINE__);//21
write(fd[1], "hello world\n", 13);
printf("%d\n", __LINE__);//23
waitpid(pid,NULL,0);
close(fd[1]);
} else if(pid == 0){
close(fd[1]);
printf("%d\n", __LINE__);//28
n = read(fd[0], line, 80);
printf("%d\n", __LINE__);//29
printf("pipe receive msg: %s", line);
sleep(2);
printf("%d\n", __LINE__);//32
n = read(fd[0], line, 80);
printf("%d\n", __LINE__);//34
close(fd[0]);
exit(0);
}
return 0;
}
輸出
28
17
19
30
pipe receive msg: hello world
21
23
33
35
從打印結(jié)果可以看出,管道通信成功了,此外還有2點:
- 讀的一端是阻塞讀,讀不到消息不返回;
- 寫的一端是非阻塞寫。