分叉的子进程是否使用相同的信号量?
- 2024-10-23 08:47:00
- admin 原创
- 64
问题描述:
假设我创建了一个信号量。如果我派生出一堆子进程,它们是否还会使用同一个信号量?
另外,假设我创建一个包含信号量的结构并分叉。所有子进程是否仍使用相同的信号量?如果不是,将该结构+信号量存储在共享内存中是否会允许子进程使用相同的信号量?
我真的很困惑我分叉的子进程如何使用相同的信号量。
解决方案 1:
假设我创建了一个信号量。如果我派生出一堆子进程,它们是否还会使用同一个信号量?
如果您使用的是 SysV IPC 信号量 ( semctl
),那么可以。如果您使用的是 POSIX 信号量 ( sem_init
),那么可以,但前提是您在创建时为 pshared 参数传递一个真值并将其放在共享内存中。
另外,假设我创建一个包含信号量的结构并分叉。所有子进程是否仍使用相同的信号量?如果不是,将该结构+信号量存储在共享内存中是否会允许子进程使用相同的信号量?
您所说的“内部信号量”是什么意思?对 SysV IPC 信号量的引用将被共享,因为信号量不属于任何进程。如果您使用 POSIX 信号量,或者使用 pthreads 互斥量和条件变量构建某些东西,则需要使用共享内存和 pshared 属性(pthreads也具有条件变量和互斥量的 pshared 属性)
请注意,使用该标志创建的匿名 mmapMAP_SHARED
在这些用途中计为(匿名)共享内存,因此无需实际创建命名的共享内存段。普通堆内存在 fork 之后不会被共享。
解决方案 2:
假设我创建了一个信号量。如果我派生出一堆子进程,它们是否还会使用同一个信号量?
这取决于您如何创建信号量,要使用 IPC 信号量执行此操作,请参见semaphore.c:简单信号量传递的说明作为示例。
另外,假设我创建一个包含信号量的结构并分叉。所有子进程是否仍使用相同的信号量?如果不是,将该结构+信号量存储在共享内存中是否会允许子进程使用相同的信号量?
为了使其工作,您的信号量需要存储在父进程和子进程之间共享的区域中,例如共享内存,而不仅仅是在堆栈或堆上创建,因为它会在进程分叉时被复制。
我真的很困惑我分叉的子进程如何使用相同的信号量。
信号量可跨线程或进程共享。跨进程共享是在操作系统级别实现的。两个或多个不同的进程可以共享同一个信号量,即使这些进程不是通过分叉单个父进程创建的。
请参阅此示例,了解如何在父进程和其子进程之间共享未命名的 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*/
for (int i = 0; i < nloop; i++) {
printf("child unlocks semaphore: %d
", i);
if (sem_post(sema) < 0) {
perror("sem_post");
}
sleep(1);
}
if (munmap(sema, sizeof(sema)) < 0) {
perror("munmap");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
if (pid > 0) {
/* back to parent process */
for (int i = 0; i < nloop; i++) {
printf("parent starts waiting: %d
", i);
if (sem_wait(sema) < 0) {
perror("sem_wait");
}
printf("parent finished waiting: %d
", i);
}
if (sem_destroy(sema) < 0) {
perror("sem_destroy failed");
exit(EXIT_FAILURE);
}
if (munmap(sema, sizeof(*sema)) < 0) {
perror("munmap failed");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
}
输出将是:
parent starts waiting: 0
child unlocks semaphore: 0
parent finished waiting: 0
parent starts waiting: 1
child unlocks semaphore: 1
parent finished waiting: 1
...
您可能还想阅读Linux 中的信号量,但请注意,给出的跨 fork 的 UNIX 信号量示例不起作用,因为作者忘记使用MAP_ANONYMOUS
中的标志mmap
。
解决方案 3:
尝试一下
子级和父级将交替增加共享变量
#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>
struct test {
sem_t mutex1;
sem_t mutex2;
int temp;
}test1;
int main(int argc, char **argv)
{
int fd, i,count=0,nloop=10,zero=0,*ptr;
struct test *testptr;
//open a file and map it into memory
sem_t mutex;
fd = open("log.txt",O_RDWR|O_CREAT,S_IRWXU);
write(fd,&zero,sizeof(int));
ptr = mmap(NULL, sizeof(struct test),PROT_READ |PROT_WRITE,MAP_SHARED,fd,0);
close(fd);
memcpy(ptr, &test1, sizeof(test1));
testptr = (struct test *)ptr;
// testptr = (struct test *)&test1;
/* create, initialize semaphore */
if( sem_init(&(testptr->mutex1),1,1) < 0)
{
perror("semaphore initilization");
exit(0);
}
/* create, initialize semaphore */
if( sem_init(&(testptr->mutex2),1,0) < 0)
{
perror("semaphore initilization");
exit(0);
}
if (fork() == 0) { /* child process*/
for (i = 0; i < nloop; i++) {
sem_wait(&(testptr->mutex2));
printf("child: %d
", testptr->temp++);
sem_post(&(testptr->mutex1));
}
exit(0);
/* back to parent process */
for (i = 0; i < nloop; i++) {
sem_wait(&testptr->mutex1);
printf("parent: %d
", testptr->temp++);
sem_post(&(testptr->mutex2));
}
exit(0);
}
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件