C语言中的信号量和fork()函数

4

我有以下的代码块:

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "display.h"

int main()
{
  int i;

  if (fork())
  {
    for (i=0;i<10;i++)
      display("ab");
    wait(NULL);
  }
  else
  {
    for (i=0;i<10;i++)
      display("cd\n");
  }

  return 0;
}

display.c是什么:

/* DO NOT EDIT THIS FILE!!!  */

#include <stdio.h>
#include <unistd.h>
#include "display.h"

void display(char *str)
{
  char *p;
  for (p=str; *p; p++)
  {
    write(1, p, 1);
    usleep(100);
  }
}

并且 display.h 是:

/* DO NOT EDIT THIS FILE!!!  */

#ifndef __CEID_OS_DISPLAY_H__
#define __CEID_OS_DISPLAY_H__
void display(char *);
#endif

如果我运行这段代码,输出结果将是:
abacdb
abcdab
acdbababa
cbadb
cad
bcd
cd
cd
cd
cd

我想使用信号量来实现以下输出:
abcd
abcd
abcd
....

我尝试做到这一点的方法如下:

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include "display.h"
#include <semaphore.h>
#include <stdio.h>

int main()
{


    int i, my_sem, v1,v2,t;

    my_sem = semget(IPC_PRIVATE, 1, 0600);   /* CREATE OF THE SEMAPHORES */

    struct sembuf up = {0, 1, 0};       
    struct sembuf down = {0, -1, 0};    

    if (fork())
        {

            for (i=0;i<10;i++){

                display("ab");
            semop(my_sem, &up, 1);      /* UP (); */

            wait(NULL);

            }

        }
        else
        {
            for (i=0;i<10;i++){
            semop(my_sem, &down, 1);    /* DOWN (); */

                display("cd\n");

            semop(my_sem, &up, 1);  /* UP (); */
            }


        }

    return 0;
}

我的代码输出结果为:
abcd
cd
cd
cd
cd
cd
cd
cd
cd
cd
ababababababababab

看起来只有第一次有效。我对sempaphores非常新,因此需要帮助以使我的代码运行。

感谢您的时间。


@EugeneSh。根据手册POSIX信号量允许进程和线程同步它们的操作。 - Enzo Ferber
我的教授想要使用信号量来解决这个问题。他的问题非常清晰明了。使用信号量在多进程中是否不可能?@EugeneSh。 - Aris Kantas
正如@EnzoFerber所指出的,这应该没问题... 对这些东西有点生疏。 - Eugene Sh.
@ArisKantas,看起来你正在使用旧的信号量API。从我发布的手册链接中可以看到:“System V信号量(semget(2),semop(2)等)是一种较旧的信号量API。 POSIX信号量提供了比System V信号量更简单和更好设计的接口;另一方面,与System V信号量相比,POSIX信号量的可用性较差(特别是在旧系统上)。”你是否有关于应该使用哪个API的限制? - Enzo Ferber
在父进程的循环中,您使用wait(NULL)等待子进程结束,这意味着第一次迭代将暂停直到子进程终止。这似乎符合结果。为什么会让人感到惊讶? - rici
显示剩余7条评论
1个回答

3

wait(null)等待子进程终止,在这种情况下,您需要等待子进程完全完成后才能恢复“ab”循环,因此会先显示一次“ab”,然后是所有的“cd”行。

您需要进一步考虑如何在进程之间进行通信。您可以使用信号量(它们的值)来防止一个进程在允许另一个进程继续前进时取得进展。


我认为你帮助我更好地理解了信号量。 - Aris Kantas
如果您能给我展示一个例子,那将非常有帮助。@brettkc 谢谢。 - Aris Kantas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接