c - 使用 cat、tee 和 fifos 在多线程 C 程序中从 xterm 打印和读取

标签 c multithreading cat fifo tee

我正在尝试在我的 C 程序中创建一个聊天界面。 该程序使用两个 fifo 与同时运行命令 cat fifo_outtee fifo_in >/dev/null 的 fork xterm 进行通信。 然后打开一个线程来读取 *fifo_in 中的输入 感谢 tee 来自终端,同时另一个线程在 fifo_out 中打印消息,并且内容显示在 xterm 中。

一切似乎都工作得很好......除了在终端中写入一些文本时打印消息时,将输入的文本分成两部分。这会导致段错误!

你知道为什么会这样吗?

这是一个最小的例子:

int open_terminal(pid_t *pid, int *pipe)
{
  mkfifo("fifo_in", 0600);
  mkfifo("fifo_out", 0600); 
  pid_t p = fork();
  int fd_in, fd_out;
  switch (p) {
    case -1:
      return -1;
    case 0:
        execlp("xterm", "xterm", "-e", "cat fifo_out & tee fifo_in > /dev/null", NULL);
        exit(EXIT_FAILURE);
        break;
    default:
        if ((fd_in = open("fifo_in", O_RDONLY)) == - 1)
          return -1;
        if ((fd_out = open("fifo_out", O_WRONLY)) == - 1)
          return -1;
        *pid = p;
        pipe[0] = fd_in; pipe[1] = fd_out;
        return 0;
  }
  return -1;
}


void *message_thread(void *args)
{
  int *fd_out = (int *)args;
  while (1) {
    dprintf(*fd_out, "You're awesome!\n");
    sleep(5);
  }
}


void *input_thread(void *args)
{
  int *fd_in = (int *)args;
  FILE *f = fdopen(*fd_in, "r");
  while (1) {
    size_t n;
    char *line;
    getline(&line, &n, f);
    printf("Read: %s", line);
    free(line);
    if(strcmp(line, "exit\n") == 0)
      return NULL;
  }
}


int main(int argc, char *argv[])
{
  pid_t pid;
  int pipe[2];
  if (open_terminal(&pid, pipe) == -1) {
    printf("Can't open terminal.\n");
    return 1;
  }
  pthread_t mt, it;
  pthread_create(&mt, NULL, message_thread, &pipe[1]);
  pthread_create(&it, NULL, input_thread, &pipe[0]);

  pthread_join(it, NULL);

  return 0;
}

要重现我的条件,请运行程序,输入一些文本,等待文本后打印出一些文本,然后再次键入并输入。

最佳答案

来自input_thread函数:

free(line);
if(strcmp(line, "exit\n") == 0)

首先释放line分配并指向的内存,然后立即使用该内存。这会导致未定义的行为

这还不是全部,因为您将未初始化的指针和大小传递给 getline 函数,它实际上不会分配内存,因为未初始化的局部变量具有不确定值(它看起来是随机的,不太可能为零或NULL)。将变量显式初始化为零和NULLgetline 函数将分配所需的内存。将未初始化的本地(非静态)变量用于除初始化之外的其他任何操作也会导致未定义的行为。

这可能是由于 getline 写入一些看似随机的内存而导致崩溃的未定义行为。

关于c - 使用 cat、tee 和 fifos 在多线程 C 程序中从 xterm 打印和读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37109650/

相关文章:

java - 进化模拟 - 用于计时器事件处理的持久线程

unix - 为什么 file2 在 'cat file1>file2>file3' 之后为空?

C - 检查字符串是否包含任何非空字符

Java SwingWorker 不会在任务完成时终止

c++ - 在文本压缩期间存储概率表

ios - 在不移除线程锁的情况下优化代码

arrays - Bash 脚本以特定的顺序或顺序显示结果

c - 如何停止读取 "cat/dev/urandom"?

c - 实现 malloc 时链表无法正常工作

python - 在 Python 中使用 SWIG 进行 C 扩展时安装文件出错