用于进程间通信的普通管道

时间:2013-01-20 00:19:19

标签: c linux

我正在学习在linux中使用普通管道进行父子进程之间通信的方法。基本任务只是从父进程向子进程发送消息,然后子进行一些转换并将结果传递回父进程。我显示的结果是一些随机字符,如 。我已经考虑了很长一段时间,仍然无法弄清楚这个bug。谢谢你的帮助。

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#define READ_END 0
#define WRITE_END 1

void convert(char* str);

int main(int argc, char *argv[]){
  int pid; /* Process ID */
  int status;
  char *input;
  char *read_msg_c;
  char *read_msg_p;
  int pfd1[2], pfd2[2];
  if (argc !=2){/* argc should be 2 for correct execution */
    /* We print argv[0] assuming it is the program name */
    printf("Please provide the string for conversion \n");
    exit(-1);
  }
  input = argv[1];

  if(pipe(pfd1) < 0 || pipe(pfd2) < 0){
    printf("Failed to create a pipe between parent and child \n");
    exit(-1);
  }
  if((pid = fork()) < 0){ /* Fork the process */
     printf("Fork error \n");
     exit(-1);
  }
  else if(pid > 0){ /* Parent code */
    close(pfd1[READ_END]);
    close(pfd2[WRITE_END]);
    printf("Process ID of the parent is %d. \n", getpid()); /* Print parent's process ID */
    write(pfd1[WRITE_END],input,strlen(input)+1);
    close(pfd1[WRITE_END]);

    read(pfd2[READ_END],read_msg_p,strlen(input)+1);
    printf("%s\n",read_msg_p);
    close(pfd2[READ_END]);
  }
  else if(pid == 0){ /* Child code */
    close(pfd1[WRITE_END]);
    close(pfd2[READ_END]);

    printf("Process ID of the child is %d. \n", getpid()); /* Print child's process ID */
    read(pfd1[READ_END],read_msg_c, strlen(input)+1);
    printf("Child: Reversed the case of the received string. \n");
    write(pfd2[WRITE_END],read_msg_c,strlen(input)+1);
    close(pfd1[READ_END]);
    close(pfd2[WRITE_END]);
    exit(0); /* Child exits */
   }
}

void convert(char *str){
  int i = 0;
  while (str[i]){
    if (isupper(str[i])){
      str[i] = tolower(str[i]);
    }
    else if (islower(str[i])){
      str[i] = toupper(str[i]);
    }
    i++;
  }
}

1 个答案:

答案 0 :(得分:2)

您的主要错误是您的变量read_msg_pread_msg_c是未初始化的指针。

将它们变成数组:

char read_msg_p[1024];
char read_msg_c[1024];

您似乎缺少<stdio.h>(但您不再需要<sys/types.h>)。你应该错误地检查你的读写;一旦为其分配了空间,您的读取可能会使用不同的最大大小。等

我通过查看编译器警告来发现问题:

$ gcc -O3 -g -std=c99 -Wall -Wextra pipes-14420398.c -o pipes-14420398
pipes-14420398.c: In function ‘main’:
pipes-14420398.c:40:22: warning: ‘read_msg_p’ may be used uninitialized in this function [-Wuninitialized]
pipes-14420398.c:52:22: warning: ‘read_msg_c’ may be used uninitialized in this function [-Wuninitialized]
$

忽略行号;当这些是唯一的警告时,我会适度地严重破解你的代码。但有问题的行是read()电话。


示例输出形成被黑客入侵的代码,正常工作。

$ ./pipes-14420398 string-to-convert
Process ID of the parent is 37327. 
Process ID of the child is 37328. 
Child read 18 bytes: <<string-to-convert>>
Parent read 18 bytes: <<string-to-convert>>
$

请注意,下面的代码读取18个字节(包括null),但不打印null(因为nbytes-1的{​​{1}}参数。

printf()

WhozCraig所述,还有许多其他变化可以做出。然而,这使得事情合理地干净利落。你非常接近OK。

请注意调试技巧:

  1. 编译高警告级别并修复所有警告。
  2. 打印信息,因为它可用(或在调试器中运行并观察可用的信息)。