Linux如何运行pipe1,Linux中的管道
一.管道是進(jìn)程間通信的一種重要手段,在linux中沒有使用專門的數(shù)據(jù)結(jié)構(gòu),而是借助了文件系統(tǒng)的file結(jié)構(gòu)和VFS索引節(jié)點inode。通過兩個file結(jié)構(gòu)指向同一個臨時的VFS索引節(jié)點,而這個索引節(jié)點又指向一個物理頁面實現(xiàn)的。如下圖所示:
管道的實現(xiàn)的源代碼在fs/pipe.c中,其中pipe_read()和pipe_write()是管道的讀寫函數(shù)。管道寫函數(shù)通過將字節(jié)復(fù)制到VFS索引節(jié)點指向的物理內(nèi)存而寫入數(shù)據(jù),而管道讀函數(shù)則通過復(fù)制物理內(nèi)存中的字節(jié)而讀出數(shù)據(jù)。當(dāng)然,內(nèi)核必須利用一定的機(jī)制同步對管道的訪問,為此,內(nèi)核使用了鎖、等待隊列和信號。
二.匿名管道(pipe)
常用于父子進(jìn)程,也用于有血緣關(guān)系的進(jìn)程間的通信。舉例:父進(jìn)程與子進(jìn)程之間的通信。
因為匿名管道提供的進(jìn)程通信是單向的,所以去掉上圖中子的讀(寫),去掉父的寫(讀)。就可以實現(xiàn)子寫父讀(子讀父寫)。
代碼實現(xiàn)子寫父讀:1?#include
2?#include
3?#include
4?#include
5?#include
6
7?int?main()
8?{
9???//1.創(chuàng)建管道
10???int?pipe_fd[2]={-1,-1};
11???if(pipe(pipe_fd)<0)
12???{
13?????perror("pipe");
14?????exit(1);
15
16????}
17??//?printf("0->?%d,1->?%d",pipe_fd[0],pipe_fd[1]);檢查讀寫
18??//2.創(chuàng)建進(jìn)程
19??pid_t?pid=fork();
20??if(pid<0)
21???{
22?????perror("fork");
23?????exit(2);
24
25???}
26?else?if(pid==0)
27?{
28???//子進(jìn)程
29???close(pipe_fd[0]);
30???int?count=10;
31???char?buf[]="hello?bit";
32???while(count)
33????{
34???????write(pipe_fd[1],buf,?strlen(buf));
35???????count--;
36???????sleep(1);
37????}
38???close(pipe_fd[1]);
39??}
40?else
41???{
//父進(jìn)程
42?????close(pipe_fd[1]);
43?????char?buf[1024];
44?????while(1)
45?????{
46???????memset(buf,'\0',sizeof(buf)-1);
47???????ssize_t?size=read(pipe_fd[0],buf,sizeof(buf)-1);
48???????if(size>0)
49????????{
50??????????buf[size]='\0';
51??????????printf("%s\n",buf);
52
53?????????}
54??????}
55?????}
56????close(pipe_fd[0]);
57????return?0;
58??}
1,7???????????Top
程序執(zhí)行結(jié)果:
父進(jìn)程讀取到子寫的10條信息。
使用匿名管道注意的狀況(假設(shè)都是阻塞I/O)
1.管道引用計數(shù)
定義一個count,來決定讀多少寫多少
2.寫端不關(guān)閉,并且不寫,讀端讀完,繼續(xù)等待,此時阻塞
3.讀端關(guān)閉,寫端在寫,那么寫進(jìn)程收到信號SIGPIPE,通常導(dǎo)致進(jìn)程異常中止。
4.讀端沒有關(guān)閉,但不讀數(shù)據(jù),寫端一直在寫,直到寫滿,再次阻塞或為空再寫。
匿名管道的特點總結(jié):
1.進(jìn)程之間的通信是單向的
2.用于父子進(jìn)程和有血緣關(guān)系的進(jìn)程
3.提供的是流式服務(wù)
4.管道內(nèi)部處理了數(shù)據(jù)寫齊備然后才能讀的機(jī)制
5.生命周期隨進(jìn)程。
三.命名管道(name pipe 或 FIFO)
命名管道是在shell交互地建立的,可以解決不同進(jìn)程之間的進(jìn)程問題。
代碼:client:發(fā)消息的
#include
int?main()
{
umask(0);
//創(chuàng)建命名管道
if(mkfifo("./.tmp",S_IFIFO|0666)<0)
{
perror("mkfifo");
exit(1);
}
int?fd=open("./.tmp",O_WRONLY);//寫方式打開
if(fd<0)
{
perror("open");
exit(2);
}
char?buf[1024];
while(1)
{
memset(buf,'\0',sizeof(buf));
fflush(stdout);
ssize_t?size=read(0,buf,sizeof(buf));//從標(biāo)準(zhǔn)入上讀
buf[size]='\0';
write(fd,buf,sizeof(buf));
}
close(fd);
return?0;
}
server:接消息的
1?#include
2?#include
3?#include
4?#include
5?#include
6?#include
7?#include
8?int?main()
9?{
10
11???int?fd=open("./.tmp",O_RDONLY);
12???if(fd<0)
13????{
14??????perror("open");
15??????exit(2);
16?????}
17??char?buf[1024];
18??while(1)
19??{
20???ssize_t?size=read(fd,buf,sizeof(buf));
21???if(size>0)
22???{
23????buf[size-1]='\0';
24????printf("client?say?%s\n",buf);
25????}
26??else
27???{
28????printf("client?quit?or?error\n")???;
29????break;
30
31????}
32
33
34?}
35??close(fd);
36??return?0;
37?}
運(yùn)行結(jié)果:
client:
server:
總結(jié)
以上是生活随笔為你收集整理的Linux如何运行pipe1,Linux中的管道的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux启动守护进程失败,Ubuntu
- 下一篇: crontab命令linux,cront