千家信息网

unix 无关系进程间通信-有名管道

发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,有名管道是专用于无关系进程间的通信open("../share_fifo", O_RDONLY, 777); 这个以只读打开有名管道,会产生阻塞,直到有其它进程以写打开才会继续执行下去open("..
千家信息网最后更新 2024年11月23日unix 无关系进程间通信-有名管道
  1. 有名管道是专用于无关系进程间的通信
  2. open("../share_fifo", O_RDONLY, 777); 这个以只读打开有名管道,会产生阻塞,直到有其它进程以写打开才会继续执行下去
  3. open("../share_fifo", O_RDONLY|O_NONBLOCK, 777); 这个以只读且注明以非阻塞打开,open不会产生阻塞,导致read()函数对有无数据读完即离开
  4. open(fifo,O_WRONLY, 777) 阻塞到其它进行以读打开这个管道
  5. open(fifo,O_WRONLY|O_NONBLOCK, 777) 没有阻塞,如果没有其它进行以读打开管道会立即返回报错-1 ENXIO
  6. 写一个无读打开的管道会产生一个信号 SIGPIPE,可以捕捉以信号来进行后续处理
  7. 此例程,功能为一个服务进程 与 多个客户进程之间的通信
  8. 程序还需要进行一步完美


server.c

  1. #include <stdlib.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <limits.h>
  7. #include <string.h>
  8. #include <stdbool.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #define MAXLINE 100
  12. pid_t str_handler(char*);
  13. void handler_client_corrupt(int);
  14. static char* itoa(int);//因为itoa是一个非标准C函数,因此需要自己定义
  15. void del_fifo(void);//退出时将管道删除
  16. int main()
  17. {
  18. int fd;
  19. int count = 10;
  20. int BUF_SIZE;
  21. pid_t client_id;
  22. //注册 程序退出时执行删除管道
  23. if(atexit(del_fifo))
  24. {
  25. perror("atexit\n");
  26. exit(1);
  27. }
  28. #if 1
  29. // 创建一个客户端到服务器共享有命管道,此管道必需不存在
  30. if(0 != mkfifo("../share_fifo", 0777 ))
  31. {
  32. perror("mkfifo\n");
  33. exit(1);
  34. }
  35. fputs("share_fifo has been created\n",stdout);
  36. #endif
  37. //打开管道并设置只读
  38. fd = open("../share_fifo", O_RDONLY, S_IRUSR|S_IRGRP|S_IROTH);
  39. if(fd<0)
  40. {
  41. perror("open\n");
  42. exit(1);
  43. }
  44. //初始化缓存数组
  45. (MAXLINE > PIPE_BUF) ? (BUF_SIZE = PIPE_BUF) : (BUF_SIZE = MAXLINE);
  46. //原子操作写进fifo最大数据量,若超过会导致进行间的竟争 MAXLINE < PIPE_BUFPIPE_BUF = 4096
  47. //#define PIPE_BUF 4096
  48. //usr/lib/limits.h
  49. char buf[BUF_SIZE];
  50. memset(buf, sizeof(buf), 0);
  51. //读取数据并进行处理
  52. while(20)
  53. {
  54. //读客户端发来的信息内容,并冲洗标准输入出进行显示
  55. int num;
  56. num = read(fd, buf, BUF_SIZE);
  57. if(-1 == num)
  58. {
  59. perror("read\n");
  60. exit(1);
  61. }
  62. fputs(buf,stdout);
  63. //由于标准输出需要遇到换行符"\n"才会进行显示,而收到内容中没有换行符,使此函数进行冲洗显示
  64. putchar('\n');
  65. //回复客户端,并对回复的内容进行处理
  66. client_id = str_handler(buf);
  67. //处理回复内容字符串
  68. char str[100] = "receided successfully:";
  69. strcat(str,itoa(client_id));
  70. int len = strlen(str);
  71. char str_reply[len+1];
  72. strcpy(str_reply, str);
  73. //处理客户端路径
  74. char tmp[100]= "../";
  75. strcat(tmp,itoa(client_id));
  76. len = strlen(tmp);
  77. char path[len+1];
  78. strcpy(path,tmp);
  79. //打开对应客户端的管道进行写操作
  80. int cfd = open(path,O_WRONLY, S_IWUSR|S_IWGRP);
  81. if(cfd<0)
  82. {
  83. perror("open_1\n");
  84. exit(1);
  85. }
  86. //回复对应的客户端
  87. if(write(cfd, str_reply, (strlen(str_reply)+1) ) == -1)
  88. {
  89. perror("write\n");
  90. exit(1);
  91. }
  92. //写完后关闭对应的管道
  93. if(close(cfd))
  94. {
  95. perror("close\n");
  96. exit(1);
  97. }
  98. sleep(1);
  99. }
  100. if(close(fd))
  101. {
  102. perror("close\n");
  103. exit(1);
  104. }
  105. return 0;
  106. }
  107. pid_t str_handler(char*buf)
  108. {
  109. pid_t tmp;
  110. int len = strlen(buf);
  111. tmp = atoi(buf);
  112. printf("len :%d tmp:%d,buf:%s\n",len,tmp,buf);
  113. if( (tmp == 0) || (tmp < 0) )
  114. {
  115. return -1;
  116. }
  117. return tmp;
  118. }
  119. static char* itoa(int i)
  120. {
  121. char * local = (char*) malloc(10);
  122. memset(local,10,0);
  123. sprintf(local,"%d",i);
  124. return local;
  125. }
  126. void del_fifo(void)
  127. {
  128. if(remove("../share_fifo"))
  129. {
  130. perror("remove\n");
  131. exit(1);
  132. }
  133. }



client.c

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #define MAXLINE 100
  9. char buf[MAXLINE];
  10. char tmp[100]= "../";
  11. char* path;
  12. static char* itoa(int i)
  13. {
  14. char * local = (char*) malloc(10);
  15. memset(local,10,0);
  16. sprintf(local,"%d",i);
  17. return local;
  18. }
  19. void del_fifo(void)
  20. {
  21. if(remove(path))
  22. {
  23. perror("remove\n");
  24. exit(1);
  25. }
  26. }
  27. int main(int argc, char** argv)
  28. {
  29. int fd0 , fd1;
  30. int len;
  31. strcat(tmp,itoa(getpid()));
  32. len = strlen(tmp);
  33. char tmp_path[len+1];
  34. strcpy(tmp_path,tmp);
  35. path = tmp_path;
  36. if(0 != mkfifo(path, 0777 ))
  37. {
  38. perror("mkfifo\n");
  39. exit(1);
  40. }
  41. #if 0
  42. fd0 = open("../client0", O_RDONLY, S_IRUSR|S_IRGRP);
  43. if(fd0<0)
  44. {
  45. perror("open_0\n");
  46. exit(1);
  47. }
  48. #endif
  49. //处理回复内容字符串
  50. char str[10];
  51. memset(str,10,0);
  52. strcpy(str,itoa(getpid()));
  53. len = strlen(str);
  54. char str_send[len+1];
  55. strcpy(str_send, str);
  56. printf("%s\n",str_send);
  57. fd1 = open("../share_fifo", O_WRONLY, S_IWUSR|S_IWGRP);
  58. if(fd1<0)
  59. {
  60. perror("open_1\n");
  61. exit(1);
  62. }
  63. fd0 = open(path, O_RDONLY|O_NONBLOCK, S_IRUSR|S_IRGRP);
  64. if(fd0<0)
  65. {
  66. perror("open_0\n");
  67. exit(1);
  68. }
  69. int count = 10;
  70. while(count--)
  71. {
  72. if(write(fd1, str_send, (strlen(str_send)+1) ) == -1)
  73. //if(write(fd1, "test\n", 5 ) == -1)
  74. {
  75. perror("write\n");
  76. exit(1);
  77. }
  78. fputs("write complete\n",stdout);
  79. #if 0
  80. if(close(fd1))
  81. {
  82. perror("close\n");
  83. exit(1);
  84. }
  85. #endif
  86. while(read(fd0, buf, MAXLINE)<=0);
  87. printf("%s\n",buf);
  88. sleep(1);
  89. }
  90. return 0;
  91. }
附件:http://down.51cto.com/data/2362203
0