多进程管道通信问题

发布于 2022-10-15 06:34:47 字数 183 浏览 28 评论 0

两进程之间通过管道通信
管道文件为  /ab/.global/aaa.pid
如果一个进程打开管道,写内容后,unlink这个管道文件
然后管道文件aaa.pid就消失了
我看unlink的用法,不是说如果有别的程序仍然在链接文件,是不会删掉那个文件的
但这里确实删掉了,请问为什么啊?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

够运 2022-10-22 06:34:47

那个,管道是FIFO,命名的那个

心作怪 2022-10-22 06:34:47

本帖最后由 cokeboL 于 2011-05-19 15:16 编辑

“该函数(unlink)删除目录项,并将有pathname所引用文件的链接计数减1。”
“只有当链接技术达到0时,该文件的内容才可被删除。另一个条件也会组织删除文件的内容——只要有进程打开了该文件,其内容页不能删除。关闭文件时,内核首先检查打开该文件的进程数。如果该数达到0,然后内核检查其链接数,如果这个数页是0,那么就删除该文件的内容。”   
                                                                                     ——摘自APUE

首先要分清两组东西:
一是文件表项、文件的链接计数和文件内容,这三个不一样,文件表项就相当于一个个硬链接;链接计数是内核维护的文件结构中的一个成员,用于管理,有多少个文件表项链接计数就是多少;文件内容是文件本身存储的数据。
二是关闭文件和删除文件,close时如果上面第二段两个条件都满足了才会删除文件,或者用remove删除文件;unlink只是删除对应的目录项,并将链接计数减1,并不执行删除文件内容的操作,所以它并不是直接删除文件,而只是对删除文件产生间接影响。

所以当unlink时文件表项删掉了,ls查不到,但文件内容依然存在。如APUE中说,以O_CREAT参数open一个新文件,然后立刻unlink掉,可以用来做临时文件~

所以当楼主调用unlink的时候只是把文件链接计数减1,文件表项也已删除,所以查不到。但你的进程正打开该文件,文件内容暂时还没有删除,当调用close或进程退出文件close时,该文件内容才会删除。

蘸点软妹酱 2022-10-22 06:34:47

另外,这个跟管道通信好像没什么关系啊。。被题目忽悠了。。

糖粟与秋泊 2022-10-22 06:34:47

是你没认真看题!
竟然说我题目忽悠你,我忽悠你有任何好处没?

谜泪 2022-10-22 06:34:47

是你没认真看题!
竟然说我题目忽悠你,我忽悠你有任何好处没?
aychxm 发表于 2011-05-19 15:56

...

淡定淡定,跟你开个玩笑还当真了~

你问的是为啥文件删掉了对不?我回答了(虽然不知道对不对),您看下。。。

这个文件删掉了跟它是不是FIFO没直接关系,普通文件这样做应该一样子吧?你的问题跟管道通信有关吗?如果有关,请把具体问题说出来,别等人家去分析你的隐藏问题撒。。。。

奢华的一滴泪 2022-10-22 06:34:47

我确实不太了解unlink的那些概念,比如目录项,比如文件链接

我想要的功能大致是这样的:
有两个进程,需要相互通信,用的FIFO,因为有名字
第一个进程用一个名字(比如:/abc/myfifo)mkfile了一个FIFO,open,然后就读管道阻塞
读到后继续运行,处理事务,然后继续读管道阻塞
。。。循环

第二个进程是这样的:(用/abc/myfifo)mkfile,open,然后往里头写数据,然后unlink
这时候unlink竟然直接将/abc/myfifo给删掉了,导致第一个进程永远阻塞

故事与诗 2022-10-22 06:34:47

本帖最后由 cokeboL 于 2011-05-19 17:09 编辑

回复 7# aychxm

虽然删掉了,但不影响通信啊

  1. /* process 1 : serv.c */
  2. int main()
  3. {
  4.     int fd;
  5.     char buf[100];
  6.     if( mkfifo("./myfifo", 0666) == -1 )
  7.         perror( "mkfifo" ), exit(-1);
  8.     if( (fd = open("./myfifo", O_RDONLY)) == -1 )
  9.         perror( "open" ), exit(-1);
  10.     while(1){
  11.         bzero( buf, sizeof(buf) );
  12.         read( fd, buf, sizeof(buf) );
  13.         fprintf( stdout, "recv: %s", buf );
  14.     }
  15.     return 0;
  16. }
  17.         
  18.    

复制代码

  1. /* process 2: client.c */
  2. int main()
  3. {
  4.     int fd;
  5.     char buf[100];
  6.    
  7.     if( (fd = open("./myfifo", O_WRONLY)) == -1 )
  8.         perror( "open" ), exit(-1);
  9.     if( unlink("./myfifo") == -1 )
  10.         perror( "unlink" ), exit(-1);
  11.     while(1){
  12.         bzero( buf, sizeof(buf) );
  13.         fprintf( stdout, "send: " );
  14.         fgets( buf, sizeof(buf), stdin );
  15.         write( fd, buf, strlen(buf) );
  16.     }
  17.     return 0;
  18. }

复制代码运行正常的撒

  1. cokeboL@ubuntu:~$ serv
  2. recv: hehe
  3. recv: nihao
  4. recv: Hi

复制代码

  1. cokeboL@ubuntu:~$ client
  2. send: hehe
  3. send: nihao
  4. send: send: Hi
  5. send:

复制代码

猛虎独行 2022-10-22 06:34:47

进程1,你一直开着,
进程2,退出了开一次,看是否能通信

妄断弥空 2022-10-22 06:34:47

本帖最后由 cokeboL 于 2011-05-20 10:14 编辑

进程1,你一直开着,
进程2,退出了开一次,看是否能通信
aychxm 发表于 2011-05-19 23:51

进程2把管道unlink了,退出了就删掉了,文件表项也没了,再开open就会失败,当然不行了(这个我前面解释过了)。想解决可以再加上个mkfifo,不过没什么意思,要这样当初就别unlink了。。

兄弟这个case你首先纠结的是文件那块,把APUE文件那部分看下吧,否则咋给你解释撒,解释了原因你又说不懂。。。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文