栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在C中的分叉进程上使用POSIX信号量?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在C中的分叉进程上使用POSIX信号量?

您面临的问题是对

sem_init()
功能的误解。阅读手册页时, 您将看到以下内容:

pshared参数指示此信号量是在进程的线程之间还是在进程之间共享。

如果您到此为止都读完了,您将认为pshared的非零值将使信号量成为进程间信号量。但是,这是错误的。您应该继续阅读,您将了解到必须在共享内存区域中找到信号灯。为此,可以使用几个功能,如下所示:

如果pshared为非零,则信号量在进程之间共享,并且应位于共享内存的区域中(请参见shm_open(3),mmap(2)和shmget(2))。(由于fork(2)创建的子级继承了其父级的内存映射,因此它也可以访问该信号量。)任何可以访问共享内存区域的进程都可以使用sem_post(3),sem_wait(3)等对该信号量进行操作。

我发现这种方法比其他方法更为复杂,因此我想鼓励人们使用

sem_open()
而不是
sem_init()

在下面您可以看到一个完整的程序,说明了以下内容:

  • 如何在派生的进程之间分配共享内存和使用共享变量。
  • 如何在共享内存区域中初始化信号量,并由多个进程使用。
  • 如何派生多个进程并使父级等待所有子级退出。

    include / printf() /

    include / exit(), malloc(), free() /

    include / key_t, sem_t, pid_t /

    include / shmat(), IPC_RMID /

    include / errno, ECHILD /

    include / sem_open(), sem_destroy(), sem_wait().. /

    include / O_CREAT, O_EXEC /

    int main (int argc, char argv){
    int i; /
    loop variables
    /
    key_t shmkey; / shared memory key /
    int shmid; / shared memory id /
    sem_t sem; / synch semaphore //shared /
    pid_t pid; /
    fork pid /
    int
    p; / shared variable //shared /
    unsigned int n; / fork count /
    unsigned int value;/ semaphore value /

    shmkey = ftok ("/dev/null", 5);       printf ("shmkey for p = %dn", shmkey);shmid = shmget (shmkey, sizeof (int), 0644 | IPC_CREAT);if (shmid < 0){         perror ("shmgetn");    exit (1);}p = (int *) shmat (shmid, NULL, 0);   *p = 0;printf ("p=%d is allocated in shared memory.nn", *p);printf ("How many children do you want to fork?n");printf ("Fork count: ");scanf ("%u", &n);printf ("What do you want the semaphore value to be?n");printf ("Semaphore value: ");scanf ("%u", &value);sem = sem_open ("pSem", O_CREAT | O_EXCL, 0644, value); printf ("semaphores initialized.nn");for (i = 0; i < n; i++){    pid = fork ();    if (pid < 0) {            sem_unlink ("pSem");sem_close(sem);                          printf ("Fork error.n");    }    else if (pid == 0)        break;       }if (pid != 0){        while (pid = waitpid (-1, NULL, 0)){        if (errno == ECHILD) break;    }    printf ("nParent: All children have exited.n");        shmdt (p);    shmctl (shmid, IPC_RMID, 0);        sem_unlink ("pSem");       sem_close(sem);              exit (0);}else{    sem_wait (sem);    printf ("  Child(%d) is in critical section.n", i);    sleep (1);    *p += i % 3;       printf ("  Child(%d) new value of *p=%d.n", i, *p);    sem_post (sem);    exit (0);}

    }

输出值

./a.out shmkey for p = 84214791p=0 is allocated in shared memory.How many children do you want to fork?Fork count: 6 What do you want the semaphore value to be?Semaphore value: 2semaphores initialized.  Child(0) is in critical section.  Child(1) is in critical section.  Child(0) new value of *p=0.  Child(1) new value of *p=1.  Child(2) is in critical section.  Child(3) is in critical section.  Child(2) new value of *p=3.  Child(3) new value of *p=3.  Child(4) is in critical section.  Child(5) is in critical section.  Child(4) new value of *p=4.  Child(5) new value of *p=6.Parent: All children have exited.

检查还不错,

shmkey
因为
ftok()
失败时返回-1。但是,如果您有多个共享变量,并且
ftok()
函数多次失败,则具有
shmkey
with值的共享变量
-1
将驻留在共享内存的同一区域中,从而导致一个更改影响另一个。因此,程序执行将变得混乱。为了避免这种情况,最好检查是否
ftok()

返回-1(最好是签入源代码,而不是像我一样打印到屏幕上,尽管我想向您显示键值以防发生冲突)。

请注意如何声明和初始化信号量。它与您在问题(

sem_t sem
vs
sem_t*sem
)中所做的不同。此外,您应该使用它们在本示例中显示的形式。您不能在中定义
sem_t*
和使用它
sem_init()



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/371108.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号