Моя программа должна увеличивать счетчик строго попеременно, используя 2 потока и синхронизируя их с помощью файла канала. Я знаю, что это не имеет особого смысла, но это университетская задача. Проблема работает, если я запускаю ее, например, с CodeBlocks, но она ничего не печатает, когда я запускаю программу из терминала Linux, и я не могу понять, почему. Есть идеи? Вот мой код:
#include <stdlib.h>
#include <pthread.h>
#include <wait.h>
#include <unistd.h>
#include <string.h>
int contor;
int fd[2];
void* thread_function(void* arg) {
int* th = (int*)arg;
char x = 'x';
while(1)
{
if (*th == 0 && contor % 2 == 0 && contor < 100) {
close(fd[0]);
write(fd[1], &x, 1);
contor++;
printf("Counter: %d incremented by thread: %ld\n", contor, pthread_self());
sleep(0);
if (contor >= 100)
{
pthread_exit(NULL);
}
} else if (*th == 1 && contor % 2 == 1 && contor < 100){
close(fd[1]);
read(fd[0], &x, 1);
contor++;
printf("Counter: %d incremented by thread: %ld\n", contor, pthread_self());
if (contor >= 100)
{
pthread_exit(NULL);
}
}
if (contor >= 100)
{
pthread_exit(NULL);
}
}
}
void main(int argc, char** argv) {
int tr1 = 0;
int tr2 = 0;
pthread_t t1, t2;
int th0 = 0;
pipe(fd);
tr1 = pthread_create(&t1, NULL, &thread_function, (void*)&th0);
if (tr1) {
printf("Error creating thread #1!");
}
int th1 = 1;
tr2 = pthread_create(&t2, NULL, &thread_function, (void*)&th1);
if (tr2) {
printf("Error creating thread #2!");
}
pthread_join(t1, NULL);
pthread_join(t2, NULL);
}
Я компилирую файл, используя: gcc -o ex.exe ex.c -lpthread
Я запускаю исполняемый файл, используя: ./ex.exe
Урок дня: проверка Всегда на наличие ошибок.
Когда я запускаю эту программу в отладчике, она завершается SIGPIPE. Я не могу себе представить, почему это должно работать в IDE. Код на самом деле не использует конвейер для синхронизации, но переменная счетчика определяет, какой поток может увеличивать счетчик. Возможный механизм синхронизации с использованием канала может заключаться в том, что все потоки используют блокирующее чтение одного байта, функция main
сначала записывает один байт, затем поток, который успешно прочитал байт, выполнит некоторую работу и снова запишет байт. Но не гарантируется, что другой поток прочитает байт.
Казалось бы, есть смысл использовать два пайпа для синхронизации чередующихся потоков.
Дескрипторы файлов совместно используются всеми потоками процесса. Одна из ваших тем закрывает один конец трубы (fd[0]
) и пишет другой конец трубы (fd[1]
). Другой ваш поток закрывает другой конец канала (fd[1]
) и читает другой конец канала (fd[0]
). Кроме того, они закрываются несколько раз в цикле while
.
Избавление от вызовов close(fd[0])
и close(fd[1])
в thread_function
немного поможет. Могут быть и другие проблемы в thread_function
, потому что программа перестала выдавать результат после того, как счетчик достиг значения 3
, когда я пробовал.
Совет: используйте две трубы.
Я думаю, проблема в том, что вы закрываете файловые дескрипторы канала, в то время как они могут понадобиться другому потоку. Дескрипторы файлов принадлежат процессам, а не потокам.