【问题标题】:Scanf doesn't work properly in multiprocessing with mutexScanf 在使用互斥锁的多处理中无法正常工作
【发布时间】:2021-09-23 14:11:09
【问题描述】:

我将程序与在父进程和子进程之间共享的互斥锁同步,但它不像我预期的那样工作,我期望:我输入 num 然后输出它,对于另一个进程同样如此,但只适用于一个进程。

代码的最小示例:

#include <stdio.h>
#include <stdlib.h>
// for multiprocessing
#include <unistd.h>
#include <sys/wait.h>
// for shared mutex
#include <pthread.h>
#include <sys/mman.h>

pthread_mutex_t mutex;
pthread_mutexattr_t mutexattr;

int main()
{
    pthread_mutex_t *shared_mutex;
    pthread_mutexattr_init(&mutexattr);
    pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&mutex, &mutexattr);
    shared_mutex = (pthread_mutex_t *)mmap(NULL, sizeof(mutex), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);

    int pid = fork();
    if (pid == -1) {
        perror("fork() failed\n");
        exit(1);
    }
    if (pid == 0) {
        int num;
        pthread_mutex_lock(shared_mutex);
        printf("enter num for child: ");
        scanf("%d", &num);
        pthread_mutex_unlock(shared_mutex);

        pthread_mutex_lock(shared_mutex);
        printf("num in child: %d\n", num);
        pthread_mutex_unlock(shared_mutex);

        return 0;
    } else {
        int num;
        pthread_mutex_lock(shared_mutex);
        printf("enter num for parent: ");
        scanf("%d", &num);
        pthread_mutex_unlock(shared_mutex);

        pthread_mutex_lock(shared_mutex);
        printf("num in parent: %d\n", num);
        pthread_mutex_unlock(shared_mutex);

        wait(NULL);
    }

    pthread_mutexattr_destroy(&mutexattr);
    pthread_mutex_destroy(&mutex);
    munmap(shared_mutex, sizeof(mutex));

    return 0;
}

在运行时它可以无限工作:

【问题讨论】:

  • 你初始化mutex;你没有初始化shared_mutex。你很不幸它没有崩溃。回顾一下。我希望在父进程和子进程中有不同的提示和响应,以便您可以分辨哪个在工作,哪个不在工作。
  • @Someprogrammerdude:PTHREAD_PROCESS_SHARED 标志和pthread_mutexattr_setpshared() 函数应该使相关的互斥锁在进程之间可访问。
  • @Someprogrammerdude hmm 我在某个站点看到了这个例子,好的,那么如何同步两个进程的 I/O?

标签: c linux multiprocessing scanf mutex


【解决方案1】:

您没有跨进程共享实际的 mutex 互斥锁。相反,您正在共享一个不是互斥锁的零初始化内存。

这段代码创建了一个名为 mutex 的互斥体,它是 main() 中的一个局部变量:

pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&mutex, &mutexattr);

此代码创建了一个完全不相关的共享内存块,其中包含一堆与任何互斥锁无关的零初始化字节,尽管名称和类型无关shared_mutex 指针变量:

pthread_mutex_t *shared_mutex;
    .
    .
    .
shared_mutex = (pthread_mutex_t *)mmap(NULL, sizeof(mutex),
    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);

这两个内存区域彼此完全没有关系,只是在同一个进程中进行内存。 mutex 指的是 main() 本地的互斥锁。 shared_mutex 指的是一堆零。

需要在共享内存中创建互斥锁:

pthread_mutex_t *shared_mutex;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
shared_mutex = (pthread_mutex_t *)mmap(NULL, sizeof(mutex),
    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
pthread_mutex_init(shared_mutex , &mutexattr);

互斥体和共享内存的清理留作练习...

【讨论】:

    猜你喜欢
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 2012-07-31
    • 1970-01-01
    相关资源
    最近更新 更多