首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >派生的子进程是否使用相同的信号量?

派生的子进程是否使用相同的信号量?
EN

Stack Overflow用户
提问于 2011-07-28 00:33:10
回答 3查看 17.9K关注 0票数 9

假设我创建了一个信号量。如果我派生一堆子进程,它们还会使用相同的信号量吗?

另外,假设我创建了一个内部带有信号量和forked的结构。是否所有子进程仍然使用相同的信号量?如果不是,那么将struct+semaphores存储在共享内存中是否允许子进程使用相同信号量?

我真的很困惑我的forked子进程如何使用相同的信号量。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-28 02:00:13

假设我创建了一个信号量。,

。如果我派生一堆子进程,它们还会使用相同的信号量吗?

如果您使用的是SysV IPC信号量(semctl),则为yes。如果您正在使用POSIX信号量(sem_init),那么可以,但是在创建时使用only if you pass a true value for the pshared argument,并将其放在共享内存中。

另外,假设我创建了一个内部带有信号量和

的结构。是否所有子进程仍然使用相同的信号量?如果不是,那么将struct+semaphores存储在共享内存中是否允许子进程使用相同信号量?

你说“信号量在里面”是什么意思?对SysV IPC信号量的引用将是共享的,因为信号量不属于任何进程。如果您正在使用POSIX信号量,或者使用pthreads和condvar构造一些东西,那么您将需要使用共享内存和pshared属性(对于condvarsmutexes,pthread也有一个pshared属性)

请注意,出于这些目的,使用MAP_SHARED标志创建的匿名mmap将计入(匿名)共享内存,因此没有必要实际创建一个命名的共享内存段。在fork之后,普通堆内存将不会被共享。

票数 11
EN

Stack Overflow用户

发布于 2011-07-28 00:54:28

假设我创建了一个信号量。,

。如果我派生一堆子进程,它们还会使用相同的信号量吗?

这取决于您是如何创建信号量的,要使用进程间通信信号量做到这一点,请参阅semaphore.c: Illustration of simple semaphore passing的示例。

另外,假设我创建了一个内部带有信号量和

的结构。是否所有子进程仍然使用相同的信号量?如果不是,那么将struct+semaphores存储在共享内存中是否允许子进程使用相同信号量?

为此,您的信号量需要存储在父进程和子进程之间共享的区域中,例如共享内存,而不仅仅是在堆栈或堆上创建,因为它将在进程派生时被复制。

我真的很困惑为什么我的forked子进程可以使用相同的信号量。

信号量可以在线程或进程之间共享。跨进程共享是在操作系统级别实现的。两个或多个不同的进程可以共享相同的信号量,即使这些进程不是通过派生单个父进程创建的。

请参阅此示例,了解如何在父进程及其子进程之间共享未命名的UNIX信号量(要使用gcc进行编译,您将需要-pthread标志):

代码语言:javascript
运行
复制
#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\n", 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\n", i);
      if (sem_wait(sema) < 0) {
        perror("sem_wait");
      }
      printf("parent finished waiting: %d\n", 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);
  }
}

输出将为:

代码语言:javascript
运行
复制
parent starts waiting: 0
child unlocks semaphore: 0
parent finished waiting: 0
parent starts waiting: 1
child unlocks semaphore: 1
parent finished waiting: 1
...

您可能也想阅读Semaphores in Linux,但请注意,给出的跨fork的UNIX信号量的示例不起作用,因为作者忘记在mmap中使用MAP_ANONYMOUS标志。

票数 8
EN

Stack Overflow用户

发布于 2011-10-29 18:58:15

尝尝这个

子变量和父变量将交替递增共享变量

代码语言:javascript
运行
复制
#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\n", 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\n", testptr->temp++);
    sem_post(&(testptr->mutex2));
  }
  exit(0);
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6847973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档