Канал между потоками

Все о программировании под *nix
Firix
Заглянувший
Сообщения: 1
Зарегистрирован: 27 май 2006, 16:53

Канал между потоками

Сообщение Firix »

Мне нужно организовать безымянный канал между двумя потоками, первый поток должен писать в канал, второй - читать из него. Делаю следующим образом:

#include <stdlib>
#include <stdio>
#include <unistd>
#include <pthread>

static pthread_mutex_t mutex;

void* thread1_f(void* arg)
{
close(fds[0]);
int a = 2000;
pthread_mutex_lock(&mutex);
write(fds[1], &a, sizeof(int));
pthread_mutex_unlock(&mutex);
sleep(1);
close(fds[1]);

return NULL;
}

void* thread2_f(void* arg)
{
close(fds[1]);
int a;
pthread_mutex_lock(&mutex);
read(fds[0], &a, sizeof(int));
pthread_mutex_unlock(&mutex);
printf("%d\n", a);
close(fds[0]);

return NULL;
}


int main()
{
int fds[2];
pipe(fds);

pthread_mutex_init(&mutex, NULL);

pthread_t thread1_id;
pthread_t thread2_id;

pthread_create(&thread1_id, NULL, &thread1_f, &fds);
pthread_create(&thread2_id, NULL, &thread2_f, &fds);

pthread_join(thread1_id, NULL);
pthread_join(thread2_id, NULL);

pthread_mutex_destroy(&mutex);

return 0;
}


Но во втором потоке функция read возвращает ошибку EBADF.
Подскажите, пожалуйста, где и что я сделал неправильно?

Аватара пользователя
red f0x
Неотъемлемая часть форума
Сообщения: 338
Зарегистрирован: 08 мар 2004, 01:41

Сообщение red f0x »

Немного странно, что переменная fds не глобальная. Как Ваши потоки к ней обращаются?

Уместно внести такое изменение в функции потоков, если Вы не хотите fds глобальной переменной:

Код: Выделить всё

void* thread1_f (arg)

      void* arg;
{
      int* fds = arg;

      /* close (fds [0]); */
      /* закомментировано мною - объяснение см. ниже */
      int a = 2000;
      pthread_mutex_lock (&mutex);
      write(fds [1], &a, sizeof (int));
      pthread_mutex_unlock (&mutex);
      sleep (1);
      /* close (fds [1]); */

     return NULL;
}


Далее, учитывая то, что это не полноценные процессы (потоки) то когда первая функция-поток закрывает канал для чтения - то она закрывает его в рамках всего процесса - само собой, это действует и для потоков, порождённых процессом (в случае с fork()'d процессов такой ситуации не наблюдается ;-) - за объяснениями см. man fork). Второй поток ничего не сможет прочитать по этой причине. Правда я не совсем понимаю, откуда у Вас нарисовалось EBADF, там где должен быть EPIPE... Короче, close (fds [0]), close (fd [1]) безопаснее делать в main ().
Ну какая работа со строками может быть в языке, название которого является не строкой, а символом? (c) Sergue E. Leontiev

Ответить