【发布时间】:2014-02-23 16:26:26
【问题描述】:
我了解信号量用于同步进程以访问共享内存。
基本上我不明白要创建多少个信号量集?
假设,我只有一段共享内存,两个进程将访问它。然后,只创建一个信号量。
但是如果我有三个或更多进程将访问相同的共享内存,那么它是否需要更多的信号量集?
信号量集的创建数量取决于什么条件?
提前致谢。
【问题讨论】:
标签: c semaphore shared-memory
我了解信号量用于同步进程以访问共享内存。
基本上我不明白要创建多少个信号量集?
假设,我只有一段共享内存,两个进程将访问它。然后,只创建一个信号量。
但是如果我有三个或更多进程将访问相同的共享内存,那么它是否需要更多的信号量集?
信号量集的创建数量取决于什么条件?
提前致谢。
【问题讨论】:
标签: c semaphore shared-memory
它不依赖于访问资源的进程数。信号量用于避免同时访问资源。如果您只有一种资源,请使用一种资源初始化信号量。一旦一个进程占用了资源,其他 2 个或更多进程等待资源被释放。一旦根据进程状态/调度释放资源,其他进程之一将占用该资源。
顺序会像
使用一个资源初始化: sem_init()
占用资源: sem_wait() 或 sem_timedwait()
释放资源: sem_post()
【讨论】:
如果您使用的是 semctl(IPC 信号量),那么您需要创建一个信号量。如果您使用的是 POSIX 信号量 (sem_init),那么也可以使用一个,但前提是您在创建时为 pshared 参数传递了一个真值并将其放置在共享内存中。
信号量可以跨线程或进程共享。跨进程共享是在操作系统层面实现的。两个或多个不同的进程可以共享相同的信号量,即使这些进程不是通过派生单个父进程创建的。
两种类型的信号量是 sysV 和 POSIX。想了解更多关于defference的信息请到System V IPC vs POSIX IPC
sysV 信号量在内核中维护,因此您无需为它们分配空间或将它们放在共享内存中即可共享它们。但是您确实需要一种方法来让每个使用它们的进程找到它们。
请参阅此示例以在父进程及其子进程之间共享未命名的 UNIX 信号量(要使用 gcc 编译,您需要 -pthread 标志):
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
int main(void)
{
/* place semaphore in shared memory */
sem_t *sema = mmap(NULL, sizeof(sema),
PROT_READ |PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,
-1, 0);
if (sema == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
/* create/initialize semaphore */
if ( sem_init(sema, 1, 0) < 0) {
perror("sem_init");
exit(EXIT_FAILURE);
}
int nloop=10;
int pid = fork();
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) {
/* child process*/
【讨论】:
semctl()?信号量集不是单个值,而是具有一组值。它通过包含多个信号量的信号量集来引用。每个信号量集由一个标识信号量集的 semid 和一个标识集合内的信号量的 semnum 标识。可以在一个semop() 调用上指定多个信号量操作。这些操作在信号量集中的多个信号量上是原子的。
看看 Pearce Wiki http://www.andy-pearce.com/wiki/notes/sharing_pthreads_primitives_between_processes 有一个 pthreads 互斥体和条件变量被放置在共享内存中 而是一个信号量。您可以将此解决方案扩展到两个以上的过程。
【讨论】: