multithreading 是否可以在 Linux/UNIX 上的多处理情况下使用互斥锁?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9389730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 01:18:30  来源:igfitidea点击:

Is it possible to use mutex in multiprocessing case on Linux/UNIX ?

multithreadingsynchronizationmutexmultiprocessingsemaphore

提问by user1002288

This is an interview question.

这是一道面试题。

Is it possible to use mutex in multiprocessing case on Linux/UNIX ?

是否可以在 Linux/UNIX 上的多处理情况下使用互斥锁?

My idea: No, different processes have separate memory space.

我的想法:不,不同的进程有单独的内存空间。

mutex is only used for multithreading.

互斥锁仅用于多线程。

semaphore is used for multiprocessing to do synchronization.

信号量用于多处理进行同步。

right ?

对 ?

Any comments are welcome.

欢迎提出任何意见。

thanks

谢谢

采纳答案by laksbv

Mutual exclusion locks (mutexes) prevent multiple threads from simultaneously executing critical sections of code that access shared data (that is, mutexes are used to serialize the execution of threads). All mutexes must be global. A successful call for a mutex lock by way of mutex_lock() will cause another thread that is also trying to lock the same mutex to block until the owner thread unlocks it by way of mutex_unlock(). Threads within the same process or within other processes can share mutexes.

互斥锁(互斥锁)防止多个线程同时执行访问共享数据的代码的临界区(即互斥锁用于串行化线程的执行)。所有互斥体都必须是全局的。通过 mutex_lock() 成功调用互斥锁将导致另一个试图锁定同一个互斥锁的线程阻塞,直到所有者线程通过 mutex_unlock() 将其解锁。同一进程内或其他进程内的线程可以共享互斥锁。

Mutexes can synchronize threads within the same processor in other processes. Mutexes can be used to synchronize threads between processes if the mutexes are allocated in writable memory and shared among the cooperating processes (see mmap(2)), and have been initialized for this task.

互斥体可以同步同一进程其他进程中的线程。如果互斥锁在可写内存中分配并在协作进程之间共享(请参阅 mmap(2)),并且已针对此任务进行初始化,则互斥锁可用于在进程之间同步线程。

Initialization

初始化

Mutexes are either intra-process or inter-process, depending upon the argument passed implicitly or explicitly to the initialization of that mutex. A statically allocated mutex does not need to be explicitly initialized; by default, a statically allocated mutex is initialized with all zeros and its scope is set to be within the calling process.

互斥体要么是进程内的,要么是进程间的,具体取决于隐式或显式传递给该互斥体初始化的参数。静态分配的互斥锁不需要显式初始化;默认情况下,静态分配的互斥锁用全零初始化,其范围设置为在调用进程内。

For inter-process synchronization, a mutex needs to be allo- cated in memory shared between these processes. Since the memory for such a mutex must be allocated dynamically, the mutex needs to be explicitly initialized using mutex_init().

对于进程间同步,需要在这些进程之间共享的内存中分配一个互斥锁。由于此类互斥体的内存必须动态分配,因此需要使用 mutex_init() 显式初始化互斥体。

回答by Maxim Egorushkin

It is quite possible to use a process-shared mutex.

很有可能使用进程共享的互斥锁

In fact, modern applications prefer using a process shared mutex along with process shared condition variable over a semaphore because the latter is less flexible.

事实上,现代应用程序更喜欢使用进程共享互斥锁和进程共享条件变量而不是信号量,因为后者不太灵活。

I remember using Red Hat Linux in 2004 and at that time it supported both process shared mutexes and condition variables.

我记得在 2004 年使用 Red Hat Linux,当时它支持进程共享互斥锁和条件变量。

回答by paxdiablo

Not quite. POSIX threads has a concept of a process-shared attributewhich can be used to create mutexes that can be operated on by multiple processes.

不完全的。POSIX 线程具有进程共享属性的概念,该属性可用于创建可由多个进程操作的互斥锁。

You can put such a mutex in shared memory so that multiple processes can all get at it.

您可以将这样的互斥锁放在共享内存中,以便多个进程都可以使用它。

Whether LINUX implements this., I'm not sure, I've never had a need to use it since it seems unnecessarily complex.

LINUX 是否实现了这一点,我不确定,我从来没有需要使用它,因为它看起来不必要地复杂。

For a useful precis of attributes, see my answer to this question.

有关有用的属性精确信息,请参阅我对此问题的回答

回答by nickdu

I was looking for a named mutex so that I could ensure mutual exclusion for the lifetime of a process (making sure only one process running per some set of properties). I didn't find one (looks like I might have not looked hard enough) and so I implemented my own pseudo named mutex in linux by using an abstract UNIX domain socket. Only a single bind() to that socket will succeed. The other nice thing is that the OS will cleanup the abstract UNIX domain socket if the process dies and thus doesn't cleanup the socket itself. Unfortunately I'm not sure of any way for you to "wait" on this pseudo mutex to become available.

我正在寻找一个命名的互斥锁,以便我可以确保在进程的生命周期内互斥(确保每个属性集只运行一个进程)。我没有找到(看起来我可能看起来不够努力),所以我通过使用抽象的 UNIX 域套接字在 linux 中实现了我自己的伪命名互斥锁。只有对该套接字的单个 bind() 会成功。另一个好处是,如果进程终止,操作系统将清除抽象的 UNIX 域套接字,因此不会清除套接字本身。不幸的是,我不确定您有什么方法可以“等待”这个伪互斥锁可用。

An abstract UNIX domain socket is a UNIX domain socket whose name begins with a null byte. Beware though, I believe that the entire buffer is used as the name and thus you want to ensure that you don't just memcpy or strcpy a partial string into it, or if you do make sure you first fill the entire buffer with some character.

抽象 UNIX 域套接字是名称以空字节开头的 UNIX 域套接字。不过要注意,我相信整个缓冲区都用作名称,因此您要确保不只是将部分字符串 memcpy 或 strcpy 放入其中,或者如果您确保首先用某个字符填充整个缓冲区.

All but the first bind() will fail with an errno of EADDRINUSE.

除了第一个 bind() 之外,所有的都将失败并返回 EADDRINUSE 的 errno。

// Create an abstract socket to use as a mutex.                             

int err;
int mutex_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (mutex_sock == -1)
    {
    err = errno;
    printf("main, failed creating mutex socket: %s\n",
            get_error_string(errno, error_string, sizeof(error_string)));
    log_event(LOG_LEVEL_ERROR, "main, failed creating mutex socket: "
            "%s", get_error_string(errno, error_string,
            sizeof(error_string)));
    errno = err;
    goto done;
    }

// Bind to abstract socket.  We use this as a sort of named mutex.          

struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path + 1, socket_name, sizeof(addr.sun_path) - 2);
result = bind(mutex_sock, (struct sockaddr*) &addr, sizeof(addr));
if (result == -1)
    {
    err = errno;
    if (errno == EADDRINUSE)
        {
        printf("main, failed bind to mutex socket: %s.  "
                "Another instance must be running.\n",
                get_error_string(errno,
                error_string, sizeof(error_string)));
        log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: "
                "%s.  "
                "Another instance must be running.",
                get_error_string(errno,
                error_string, sizeof(error_string)));
        }
    else
        {
        printf("main, failed bind to mutex socket: %s\n",
                get_error_string(errno, error_string,
                sizeof(error_string)));
        log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: %s",
                get_error_string(errno, error_string,
                sizeof(error_string)));
        }
    errno = err;
    goto done;
    }

Thanks, Nick

谢谢,尼克

回答by Gargi Srinivas

Yes, in general in Linux we have only unnamed mutexes due to which they cannot operate between processes. We need a semaphore to get over that.

是的,通常在 Linux 中我们只有未命名的互斥锁,因此它们不能在进程之间运行。我们需要一个信号量来解决这个问题。

In windows, they have a concept of named mutexes which lets us use mutexes across processes.

在 Windows 中,它们有一个命名互斥体的概念,它让我们可以跨进程使用互斥体。