Два потока — чтение текста из STDIN и отправка его по каналу

#c #linux #multithreading

#c #linux #многопоточность

Вопрос:

Я хочу создать два потока — один будет считывать строку из stdin, а другой будет отображать ее на экране (связь через каналы). Как я могу это сделать? Это то, что я написал до сих пор:

 #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];

void *input(void *ptr)
{
   close(first[1]);

   while(1)
   {
      char str[10];
      int resu<

      read(STDIN_FILENO, str, 10);

      result = read(first[0], amp;str, 1);
      if(result != 1)
      {
         perror("read");
         exit(3);
      }

      printf("Reader: %sn", str);
   }
}

void *output(void *ptr)
{
   close(first[0]);

   int resu<
   char str[10];

   while(1)
   {
      result = write(first[1], amp;str, 1);
      if(result != 1)
      {
         perror("write");
         exit(2);
      }

      printf("Writer: %sn", str);
   }
}

int main()
{
   pthread_t t1, t2;

   pthread_create(amp;t1, NULL, input, NULL);
   pthread_create(amp;t2, NULL, output, NULL);

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

   return 0;
}
  

Я могу скомпилировать его, но при попытке запустить его отображается ошибка «запись: неверный файловый дескриптор». На самом деле я не смог найти ни одного приличного руководства по каналам, только пару коротких кодов. Как мне это сделать?

Комментарии:

1. Нет кода для создания канала. Смотрите man 3 pipe . Также должен быть синхронизирован одновременный доступ к общим ресурсам ( first здесь ).

Ответ №1:

  • У вас перепутаны направления чтения / записи в канал, и вы закрываете канал в своих потоках.

  • Вам нужно проверить, сколько байтов вы прочитали из stdin и отправили в канал.

  • Вы не можете использовать printf() непосредственно для данных, которые вы считываете из канала, эти данные могут не быть строкой (они могут не завершаться нулем или могут быть двоичными данными)

  • Вам нужно фактически создать канал.

Вот что вы хотите, чтобы поток «ввода» выполнял:

  1. чтение из stdin
  2. запись данных, считанных на шаге 1, в канал

И поток «output»:

  1. чтение из канала
  2. запись данных, считанных на шаге 1, в стандартный вывод

Так что это должно быть:

 void *input(void *ptr)
{

   while(1)
   {
      char str[10];
      int resu<

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

      printf("Reader: %sn", str);
   }
}

void *output(void *ptr)
{

   int resu<
   char str[10];

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

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

int main()
{
   pthread_t t1, t2;
   pipe(first);
...
}