Существует два приложения: одно отправляет сигналы, а другое получает их. Я хочу разделить мьютекс, условную переменную и флаг между этими двумя приложениями. Мое решение с использованием mmap работает только с одним процессом получения, но после добавления я не могу получить блокировку, которая кажется бесплатной.
У меня нет идей, как это исправить, но я почти уверен, чтопроблема в моем способе совместного использования мьютекса через mmap.
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
int flags[MAX_PROCS];
int ready[MAX_PROCS];
} cb;
код для отправки сигналов:
int main(int argc, char **argv) {
int i, fd, ret;
char handle = '\n';
pthread_mutexattr_t attrmutex;
pthread_condattr_t attrcond;
fd = shm_open("tmp", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
ftruncate(fd, sizeof(cb));
cb *control = (cb*)mmap(NULL,
sizeof(cb),
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
0);
pthread_mutexattr_init(&attrmutex);
pthread_mutexattr_setpshared(&attrmutex, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&control->mutex, &attrmutex);
pthread_condattr_init(&attrcond);
pthread_condattr_setpshared(&attrcond, PTHREAD_PROCESS_SHARED);
pthread_cond_init(&control->cond, &attrcond);
for (i = 0; i < MAX_PROCS; i++) {
control->flags[i] = 0;
control->ready[i] = 0;
}
while (handle != 'q') {
printf("> ");
scanf("%c", &handle);
if (handle == 'p' || handle == 'P') {
for (i = 0; i < MAX_PROCS; i++) {
if (!control->ready[i])
printf("Process %d doesn't exist\n", i);
else
printf("Process %d listening\n", i);
}
}
else if (isdigit(handle)) {
i = atoi(&handle);
printf("Signal sent\n");
pthread_mutex_lock(&control->mutex);
control->flags[i]++;
pthread_cond_broadcast(&control->cond);
pthread_mutex_unlock(&control->mutex);
}
else {
printf("Choose process(es) to signal\n");
printf("P to print attached proceses\n");
printf("CTRL-C to quit\n");
}
if (handle != '\n')
scanf("%c", &handle);
}
exit(0);
}
код для приема сигналов:
int main(int argc, char **argv) {
int i, fd, br;
char handle = '\n';
fd = shm_open("tmp", O_RDWR, S_IRUSR | S_IWUSR);
ftruncate(fd, sizeof(cb));
cb *control = (cb*)mmap(NULL,
sizeof(cb),
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
0);
br = 0;
for (i = 0; i < MAX_PROCS; i++) {
pthread_mutex_lock(&control->mutex);
if(!control->ready[i]) {
control->ready[i]++;
br++;
}
else
printf("Process %d exists\n", i);
pthread_mutex_unlock(&control->mutex);
if (br)
break;
}
printf("Process %d listening\n", i);
while (1) {
pthread_mutex_lock(&control->mutex);
while (control->flags[i] == 0) {
pthread_cond_wait(&control->cond, &control->mutex);
}
printf("Signal received!\n");
control->flags[i]--;
pthread_mutex_unlock(&control->mutex);
}
exit(0);
}
как мойпроцессы прослушивания переходят в состояние ожидания, мьютекс должен быть свободен для получения путем отправки процесса, но он просто блокируется.
PS Когда я запускаю второй процесс получения, pthread_cond_wait возвращает ошибку EINVAL (неверные аргументы). Первые два процесса просто блокируют функции ожидания и широковещания. Каким-то образом совместное использование памяти еще одним процессом разрушает мьютекс и условную переменную, хранящуюся в общей памяти.