【问题标题】:Sending data between threads using pipes使用管道在线程之间发送数据
【发布时间】:2023-04-03 15:46:01
【问题描述】:

我有 3 个线程 - 我必须在第一个线程中读取一些内容,在第二个线程中计算字符数,并在第三个线程中进行输出。所以我在这里使用两个管道;对于第 1 - 2 线程和第 2 - 3 线程。

但是,它根本不起作用。我的意思是,我可以在控制台中输入字符串,但是没有任何反应,没有输出。

这里有什么问题?

另外,这是否可以在第一个线程的某个地方添加类似“在此处键入字符串:”的内容?在 while 循环中添加它似乎会产生奇怪的结果 - 它在运行程序后随机显示:P

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/stat.h>
#include <pthread.h>
#include <string.h>

int first[2];
int second[2];

void *input(void *ptr)
{
   while(1)
   {
      char str[100];
      int result;

      result = read(STDIN_FILENO, str, sizeof(str));
      if(result <= 0)
      {
         if(result == -1)
            perror("read");
         close(first[1]);
         exit(2);
      }
      if(write(first[1], str, result) != result)
      {
         perror("write");
         exit(2);
      }
   }
}

void *countChars(void *ptr)
{
   int result, result2, count = 0;
   char str[100];

   while(1)
   {
      result = read(first[0], str, sizeof(str));
      if(result <= 0)
      {
         if(result == -1)
            perror("read");
         close(first[0]);
         close(second[1]);
         exit(2);
      }
      if(write(STDOUT_FILENO, str, result) != result)
      {
         perror("write");
         exit(2);
      }

      while(str[count] != '\0') count++;

      write(second[1], &count, sizeof(count));
   }
}

void *output(void *ptr)
{
   int result2, count = 0;
   char str[100];

   while(1)
   {
      result2 = read(second[0], str, sizeof(str));
      if(result2 <= 0)
      {
         if(result2 == -1)
            perror("read");
         close(second[0]);
         exit(2);
      }
      if(write(STDOUT_FILENO, str, result2) != result2)
      {
         perror("write");
         exit(2);
      }

      while(str[count] != '\0') count++;

      printf("Writer: %d\n", count - 1);
   }
}

int main()
{
   pthread_t t1, t2, t3;

   if(pipe(first) == -1)
   {
      printf("First pipe error");
      exit(1);
   }

   if(pipe(second) == -1)
   {
      printf("Second pipe error");
      exit(1);
   }

   pthread_create(&t1, NULL, input, NULL);
   pthread_create(&t2, NULL, countChars, NULL);
   pthread_create(&t3, NULL, output, NULL);

   pthread_join(t1, NULL);
   pthread_join(t2, NULL);
   pthread_join(t3, NULL);

   return 0;
}

【问题讨论】:

  • 你为什么要使用线程来做这个?
  • 好吧,假设我读了 100 个字符……还是不行,输出是 0。
  • 您不需要阅读 100 个字符。阿尔克是一反常态的错误。即使少于 100 个,您也会阅读任何要阅读的内容。
  • 看起来您正在线程 2 中尝试将整数 write(second[1], &amp;count, sizeof(count)); 写入管道,然后在第三线程中将其作为字符串 result2 = read(second[0], str, sizeof(str)); 读取。然后你将线程 3 的输出基于while(str[count] != '\0') count++; 并且 int 的第一个字节很可能为零。所以你总是输出 0。
  • 那么第三个线程的正确输出是什么? Result2 始终为 4,不知道为什么,str 似乎是空的。

标签: c linux multithreading posix


【解决方案1】:

您希望 countChars 函数计数到换行符并写入 int "count"

void *countChars(void *ptr)
{
   int result, result2, count = 0;
   char str[100];

   while(1)
   {
      result = read(first[0], str, sizeof(str));
      if(result <= 0)
      {
         if(result == -1)
            perror("read");
         close(first[0]);
         close(second[1]);
         exit(2);
      }

      if(write(STDOUT_FILENO, str, result) != result)
      {
         perror("write");
         exit(2);
      }

      //while(str[count] != '\0') count++;
      while(str[count] != '\n') count++;

      write(second[1], &count, sizeof(count));

      count = 0;
   }
}

还有 output 函数将 int 的 sizeof 读入 int 变量中。

void *output(void *ptr)
{
   int result2, count = 0;
   //char str[100];

   while(1)
   {
      //result2 = read(second[0], str, sizeof(str));
      result2 = read(second[0], &count, sizeof(count));
      if(result2 < sizeof(count))
      {
         close(second[0]);
         exit(2);
      }

      printf("Writer: %d\n", count);
   }
}

这没问题,因为只有 countChars 正在写入第二个管道。管道写入/读取是原子的,最多 PIPE_BUF 字符,而 int 远小于该值,因此读取是可预测的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 2011-08-01
    • 2020-01-06
    • 2012-06-14
    • 1970-01-01
    相关资源
    最近更新 更多