pthread_mutex_lock не может получить блокировку - PullRequest
0 голосов
/ 20 октября 2019

Существует два приложения: одно отправляет сигналы, а другое получает их. Я хочу разделить мьютекс, условную переменную и флаг между этими двумя приложениями. Мое решение с использованием 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 (неверные аргументы). Первые два процесса просто блокируют функции ожидания и широковещания. Каким-то образом совместное использование памяти еще одним процессом разрушает мьютекс и условную переменную, хранящуюся в общей памяти.

...