这是一个面试问题。
在Linux / UNIX上的多处理案例中是否可以使用互斥?
我的想法: 不,不同的进程有独立的内存空间。
互斥锁仅用于多线程。
信号量用于多处理以进行同步。
对吗?欢迎任何评论。
感谢
答案 0 :(得分:24)
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.
Mutexes can synchronize threads within the **same process** or
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.
初始化 互斥体是进程内或进程间依赖的 在论证中隐含地或明确地传递给了 初始化该互斥锁。静态分配的互斥锁 不需要显式初始化;默认情况下,a 静态分配的互斥锁初始化为全零 并且其范围设置在调用过程中。
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().
答案 1 :(得分:8)
很有可能使用process-shared mutex。
事实上,现代应用程序更喜欢在信号量上使用进程共享互斥锁以及进程共享条件变量,因为后者的灵活性较低。
我记得在2004年使用Red Hat Linux,当时它支持进程共享互斥锁和条件变量。
答案 2 :(得分:5)
不完全。 POSIX线程具有process-shared attribute的概念,可用于创建可由多个进程操作的互斥锁。
您可以将这样的互斥锁放在共享内存中,以便多个进程都可以使用它。
LINUX是否实现了这一点。我不确定,我从来没有需要使用它,因为它似乎不必要地复杂。
有关属性的有用精确度,请参阅我对this question的回答。
答案 3 :(得分:2)
我正在寻找一个命名的互斥锁,这样我就可以确保在进程的生命周期内互斥(确保每个属性集只运行一个进程)。我没有找到一个(看起来我可能看起来不够努力)所以我通过使用抽象的UNIX域套接字在linux中实现了我自己的伪命名互斥。只有一个bind()到该套接字才能成功。另一件好事是,如果进程终止,操作系统将清理抽象的UNIX域套接字,因此不会清除套接字本身。不幸的是,我不确定你是否可以“等待”这个伪互斥体变得可用。
抽象UNIX域套接字是UNIX域套接字,其名称以空字节开头。但要注意,我相信整个缓冲区都用作名称,因此您需要确保不只是将memcpy或strcpy部分字符串放入其中,或者确保首先使用某些字符填充整个缓冲区
除第一个bind()之外的所有内容都将失败,错误为EADDRINUSE。
// 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;
}
谢谢, 尼克
答案 4 :(得分:0)
是的,通常在Linux中我们只有未命名的互斥锁,因为它们无法在进程之间运行。我们需要一个信号量来克服它。
在Windows中,它们有一个名为互斥锁的概念,它允许我们跨进程使用互斥锁。