Невозможно отправить сигнал с помощью pthread_cond_signal другому процессу в C

Я пытаюсь реализовать проблему производителя-потребителя, используя сценарий с двумя процессами.

Процесс1 — Производитель, а Процесс2 — Потребитель. Процесс-потребитель ожидает переменной условия (pthread_cond_wait(cond)), и производитель отправит сигнал потребителю через pthread_cond_signal(cond).

Я прошел по этим ссылкам общий мьютекс и переменная условия в процессе pthread_mutexattr_setpshared</ a> везде было сказано, что можно использовать мьютекс и условную переменную в нескольких процессах,

pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED); pthread_condattr_setpshared(&condAttr, PTHREAD_PROCESS_SHARED);

В этой ссылке

общие мьютексы В качестве рекомендации void было сказано проверить, поддерживает ли моя система или нет? Я проверил и получил 200809 в качестве возвращаемого значения sysconf(_SC_THREAD_PROCESS_SHARED), что означает, что моя система поддерживает PTHREAD_PROCESS_SHARED.

Я пытаюсь отправить pthread_cond_signal от производителя (процесс-1) потребителю (процесс-2). И производитель, и потребитель используют одну и ту же инициализированную переменную мьютекса/условия.

Однако потребитель не получает сигнал. Похоже, либо сигнал не отправляется, либо он потерян.

Где я делаю ошибки? Я использую Ubuntu, gcc-4.6.3.

Вот мой код.

Производитель.с:

#include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/wait.h> #include <pthread.h> #include <sched.h> #include <syscall.h> #include <sys/stat.h> #include <errno.h> #include <sys/mman.h> #include <fcntl.h> #include <stdbool.h> pthread_cond_t* condition; pthread_mutex_t* mutex; #define OKTOWRITE «/oktowrite» #define MESSAGE «/message» #define MUTEX «/lock» struct shared_use_st { bool conditionSatisfied; }; struct shared_use_st *shared_stuff; void create_shared_memory() { int shmid; void *shared_memory=(void *)0; shmid =shmget( (key_t)1234, 4096, 0666 | IPC_CREAT ); if (shmid == -1) { fprintf(stderr,»shmget failedn»); exit(EXIT_FAILURE); } shared_memory =shmat(shmid, (void *)0,0); if(shared_memory == (void *)-1) { fprintf(stderr,»shmat failedn»); exit(EXIT_FAILURE); } shared_stuff = (struct shared_use_st *)shared_memory; } int main() { int des_cond, des_msg, des_mutex; int mode = S_IRWXU | S_IRWXG; des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode); if (des_mutex < 0) { perror(«failure on shm_open on des_mutex»); exit(1); } if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1) { perror(«Error on ftruncate to sizeof pthread_cond_tn»); exit(-1); } mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0); if (mutex == MAP_FAILED ) { perror(«Error on mmap on mutexn»); exit(1); } des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode); if (des_cond < 0) { perror(«failure on shm_open on des_cond»); exit(1); } if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1) { perror(«Error on ftruncate to sizeof pthread_cond_tn»); exit(-1); } condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0); if (condition == MAP_FAILED ) { perror(«Error on mmap on conditionn»); exit(1); } /* set mutex shared between processes */ pthread_mutexattr_t mutexAttr; pthread_mutexattr_init(&mutexAttr); pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(mutex, &mutexAttr); /* set condition shared between processes */ pthread_condattr_t condAttr; pthread_condattr_init(&condAttr); pthread_condattr_setpshared(&condAttr, PTHREAD_PROCESS_SHARED); pthread_cond_init(condition, &condAttr); create_shared_memory(); shared_stuff->conditionSatisfied=0; int count=0; while(count++<10) { pthread_mutex_lock(mutex); shared_stuff->conditionSatisfied=1; pthread_mutex_unlock(mutex); pthread_cond_signal(condition); printf(«signal sent to consumer, %dn»,count); sleep(3); } pthread_condattr_destroy(&condAttr); pthread_mutexattr_destroy(&mutexAttr); pthread_mutex_destroy(mutex); pthread_cond_destroy(condition); shm_unlink(OKTOWRITE); shm_unlink(MESSAGE); shm_unlink(MUTEX); return 0; }

Потребитель.c:

#include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/wait.h> #include <pthread.h> #include <sched.h> #include <syscall.h> #include <sys/stat.h> #include <errno.h> #include <sys/mman.h> #include <fcntl.h> #include <stdbool.h> pthread_cond_t* condition; pthread_mutex_t* mutex; #define OKTOWRITE «/oktowrite» #define MESSAGE «/message» #define MUTEX «/lock» struct shared_use_st { bool conditionSatisfied; }; struct shared_use_st *shared_stuff; void create_shared_memory() { int shmid; void *shared_memory=(void *)0; shmid =shmget( (key_t)1234, 4096, 0666 | IPC_CREAT ); if (shmid == -1) { fprintf(stderr,»shmget failedn»); exit(EXIT_FAILURE); } shared_memory =shmat(shmid, (void *)0,0); if(shared_memory == (void *)-1) { fprintf(stderr,»shmat failedn»); exit(EXIT_FAILURE); } shared_stuff = (struct shared_use_st *)shared_memory; } int main() { int des_cond, des_msg, des_mutex; int mode = S_IRWXU | S_IRWXG; des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode); if (des_mutex < 0) { perror(«failure on shm_open on des_mutex»); exit(1); } if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1) { perror(«Error on ftruncate to sizeof pthread_cond_tn»); exit(-1); } mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0); if (mutex == MAP_FAILED ) { perror(«Error on mmap on mutexn»); exit(1); } des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode); if (des_cond < 0) { perror(«failure on shm_open on des_cond»); exit(1); } if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1) { perror(«Error on ftruncate to sizeof pthread_cond_tn»); exit(-1); } condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0); if (condition == MAP_FAILED ) { perror(«Error on mmap on conditionn»); exit(1); } /* set mutex shared between processes */ pthread_mutexattr_t mutexAttr; pthread_mutexattr_init(&mutexAttr); pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(mutex, &mutexAttr); /* set condition shared between processes */ pthread_condattr_t condAttr; pthread_condattr_init(&condAttr); pthread_condattr_setpshared(&condAttr, PTHREAD_PROCESS_SHARED); pthread_cond_init(condition, &condAttr); create_shared_memory(); shared_stuff->conditionSatisfied=0; while(1) { printf(«Receiver waits on for signal from hello1.c n»); pthread_mutex_lock(mutex); while(!shared_stuff->conditionSatisfied) pthread_cond_wait(condition, mutex); pthread_mutex_unlock(mutex); printf(«Signal received, wake up!!!!!!!!n»); //reset pthread_mutex_lock(mutex); shared_stuff->conditionSatisfied=0; pthread_mutex_unlock(mutex); } }

Мне кажется, что вы неправильно используете разделяемую память: вы вызываете в обоих процессах shm_open с O_CREATE, а также ftruncate. Только один процесс должен создать сегмент разделяемой памяти и изменить его размер. Другой должен прикрепиться к нему.   —  person bholanath    schedule 18.01.2016

Вы пытались поделиться чем-то между двумя процессами, прежде чем работать с мьютексом?   —  person bholanath    schedule 18.01.2016

@terencehill, AFIK, другой процесс сначала проверит, существует ли уже общая память или нет. Если он уже есть, он не создаст новый, а только присоединится к существующему.   —  person bholanath    schedule 18.01.2016

@terencehill, проблема в том, что обновленное значение conditionSatisfied не отображается в потребительском процессе.   —  person bholanath    schedule 18.01.2016

В каком порядке происходят события? Вы усекаете как производителя, так и потребителя.   —  person bholanath    schedule 18.01.2016

Более того, вы смешиваете старый shmget/shmat с sum_open, что меня немного сбивает с толку.   —  person bholanath    schedule 18.01.2016

проблема заключается в том, что обновленное значение conditionSatisfied не отображается в процессе потребителя. Посмотрите на сгенерированные инструкции и убедитесь, что проверка не была оптимизирована. Вы также можете добавить некоторый код для отправки чего-либо в stderr в цикле потребителя while, чтобы убедиться, что потребитель получает сигнал.   —  person bholanath    schedule 18.01.2016

@terencehill Кроме того, сигнал также не отправляется потребителю. Если я удалю предикат, то while(!shared_stuff-›conditionSatisfied) все равно потребитель не проснется.   —  person bholanath    schedule 18.01.2016

@AndrewHenle Я тебя не понял. Я уже использовал gcc -O0 для отключения всей оптимизации.   —  person bholanath    schedule 18.01.2016

@terencehill, сначала я запускаю потребителя, поэтому он ждет сигнала от производителя, затем я запускаю производителя.   —  person bholanath    schedule 18.01.2016

Итак, усечение в производителе бессмысленно, но не должно быть проблемой.   —  person bholanath    schedule 18.01.2016

Источник: ledsshop.ru

Стиль жизни - Здоровье!