免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2453 | 回复: 10
打印 上一主题 下一主题

请教关于有名管道实现进程通信的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-17 14:18 |只看该作者 |倒序浏览
我现在想编写两个函数,分别用于向fifo中写一个字符串和从fifo中读取此字符串,
但我写了一下代码,总是实现不了,请教高手是什么原因?


  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>

  6. int write_to_fifo (char *data);
  7. int read_from_fifo (char *data, int len);


  8. int write_to_fifo (char *data)
  9. {
  10.         int        len, lens;
  11.         int        fd;
  12.         int         n;
  13.        
  14.         len = strlen (data);
  15.         printf ("strlen (data) is :%d\n", len);
  16.         lens = len + 1;
  17.        
  18.        
  19.         fd = open ("fifo", O_WRONLY | O_NONBLOCK);
  20.         if ((n = write (fd, data, lens)) < 0)
  21.         {
  22.                 printf ("write to fifo error\n");
  23.                 return -1;
  24.         }
  25.         close (fd);
  26.         return lens;
  27. }

  28. int read_from_fifo (char *data, int len)
  29. {
  30.         int         fd;
  31.         int         num;
  32.        
  33.         data = (char *)malloc (sizeof (char) * (len + 1));       
  34.         fd = open ("fifo", O_RDONLY | O_NONBLOCK);
  35.         num = read (fd, data, len);
  36.         printf ("num = %d\n", num);
  37.         close (fd);
  38.         unlink ("fifo");
  39.         return 0;
  40. }

  41. int main (int argc, char **argv)
  42. {
  43.         char *s = NULL;
  44.         char *buf = NULL;
  45.         int  m;
  46.         int         err;
  47.         pid_t        pid;

  48.         s = (char *)malloc (sizeof (char) * 8);
  49.         s = "abcdefg";       
  50.         err = mkfifo ("fifo", 0666);
  51.         printf ("mkfifo return is %d\n", err);
  52.         if ((pid = fork ()) == 0)
  53.         {
  54.                 sleep (1);
  55.                 read_from_fifo (buf, m);
  56.                 printf ("read from fifo: %s\n", buf);
  57.                 exit (0);
  58.         }
  59.         else if (pid > 0)
  60.         {
  61.                 m = write_to_fifo (s);
  62.                 if (m < 0)
  63.                         printf ("write_to_fifo error\n");
  64.                 printf ("m = %d\n", m);
  65.        
  66.         }
  67.         return 0;
  68. }
复制代码

[ 本帖最后由 johncby 于 2007-1-17 14:20 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-01-17 15:01 |只看该作者
帮顶一下,为什么没有人回答他的问题呢。
高手出来一下。

论坛徽章:
0
3 [报告]
发表于 2007-01-17 15:53 |只看该作者
问题有几个
1、最严重的问题,你在滥用malloc
   s = (char *)malloc (sizeof (char) * ;
   s = "abcdefg";
   这样你的malloc还有用吗??结果是内存泄漏
2、把读写函数里面的fd = open ("fifo", O_RDONLY | O_NONBLOCK);改成fd = open ("fifo", 0666);
   你的程序读写报错的时候你可以跟踪一下errno
3、读函数里面的malloc是不能把你需要的值传出的,函数return后,内存就释放了,你malloc申请的内存再次泄漏

论坛徽章:
0
4 [报告]
发表于 2007-01-17 16:02 |只看该作者
除了楼上说的问题外
主要是:

  1. if ((pid = fork ()) == 0)
复制代码

不能够这样写的,
应该

  1.         pid = fork ();
  2.         if (pid == 0)
复制代码


还有你读写命令管道的时候,不能写一次关掉,然后再读,管道的作用不是消息队列那样的存很多信息,而是一个通道,不能再里面存信息(正确的说可以存PIPE_BUF长度的信息)。用法基本是读写进程描述符都打开,然后互相通信,通信完毕后关掉描述符号,而不是存在里面。

简单帮你调通管道,还又不少错误,自己改吧。

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <errno.h>

  7. int write_to_fifo (char *data,int fd)
  8. {
  9.         int        len, lens;
  10.         int         n;
  11.       
  12.         len = strlen (data);
  13.         printf ("strlen (data) is :%d\n", len);
  14.         lens = len + 1;
  15.       
  16.       
  17.         if ((n = write (fd, data, lens)) < 0)
  18.         {
  19.                 printf ("write to fifo error\n");
  20.                 return -1;
  21.         }
  22.         printf ("write to fifo %d\n",n);
  23.         sleep(2);
  24.         return lens;
  25. }

  26. int read_from_fifo (char *data, int len,int fd)
  27. {
  28.         int         num;
  29.       
  30.         data = (char *)malloc (sizeof (char) * (len + 1));
  31.         num = read (fd, data, len);
  32.         printf ("num = %d,data[%s] \n", num,data);
  33.         unlink ("fifo");
  34.         return 0;
  35. }

  36. int main (int argc, char **argv)
  37. {
  38.         char *s = NULL;
  39.         char *buf = NULL;
  40.         int  m;
  41.         int         err;
  42.         pid_t        pid;
  43.         int fdr;
  44.         int fdw;

  45.         s = (char *)malloc (sizeof (char) * 8);
  46.         s = "abcdefg";      
  47.         err = mkfifo ("fifo", 0666);
  48.         printf ("mkfifo return is %d\n", err);
  49.         pid = fork ();
  50.         if (pid == 0)
  51.         {
  52.                 fdr = open ("fifo", O_RDONLY | O_NONBLOCK);
  53.                 sleep (2);
  54.                 read_from_fifo (buf, m,fdr);
  55.                 printf ("read from fifo: %s\n", buf);
  56.                 close (fdr);
  57.                 exit (0);
  58.         }
  59.         else if (pid > 0)
  60.         {
  61.                 fdw = open ("fifo", O_WRONLY | O_NONBLOCK);
  62.                 m = write_to_fifo (s,fdw);
  63.                 if (m < 0)
  64.                         printf ("write_to_fifo error,errno[%d],message[%s]\n",errno,strerror(errno));
  65.                 close(fdw);
  66.                 printf ("m = %d\n", m);
  67.       
  68.         }
  69.         return 0;
  70. }
复制代码

[ 本帖最后由 hmilymb 于 2007-1-17 16:29 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2007-01-17 16:34 |只看该作者
fdr = write ("fifo", O_WRONLY | O_NONBLOCK);
这样写是不行的
看看帮助,WRONLY的时候加O_NONBLOCK是会报错的,不能加这个参数

[ 本帖最后由 wyaccent 于 2007-1-17 18:43 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2007-01-17 18:43 |只看该作者
原帖由 hmilymb 于 2007-1-17 16:02 发表
除了楼上说的问题外
主要是:

  1. if ((pid = fork ()) == 0)
复制代码

不能够这样写的,
应该

  1.         pid = fork ();
  2.         if (pid == 0)
复制代码




可以这样写。再用 else if 和 else 语句来判断其它情况即可

====

论坛徽章:
0
7 [报告]
发表于 2007-01-17 20:36 |只看该作者
原帖由 langue 于 2007-1-17 18:43 发表


可以这样写。再用 else if 和 else 语句来判断其它情况即可

====



楼上说对了。


我前几天发现
if( pid = fork() < 0 ){
}else if (pid == 0){
} else {
}

出现错误,误以为是不能够这样写,
原来是=比<优先级低导致的。



[ 本帖最后由 hmilymb 于 2007-1-17 20:37 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2007-01-17 20:54 |只看该作者
关键的错误是open (...,O_WRONLY)的时候不能加O_NONBLOCK
  When opening a FIFO with O_RDONLY or O_WRONLY set:

  If O_NONBLOCK is set:
          An open for reading only returns without delay. An open for writing
          only returns an error if no process currently has the file open for
          reading.


不过楼主的程序其他漏洞实在很多

论坛徽章:
0
9 [报告]
发表于 2007-01-17 20:56 |只看该作者
原帖由 wyaccent 于 2007-1-17 20:54 发表
关键的错误是open (...,O_WRONLY)的时候不能加O_NONBLOCK
  When opening a FIFO with O_RDONLY or O_WRONLY set:

  If O_NONBLOCK is set:
          An open for reading only returns without delay. An open for writing
          only returns an error if no process currently has the file open for
          reading.


不过楼主的程序其他漏洞实在很多


不过,如果允许我再说得确切一些的话,就是:错误多。漏洞,在代码方面有其特定的含义。

====

论坛徽章:
0
10 [报告]
发表于 2007-01-17 21:01 |只看该作者
谢谢版主纠正
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP