【问题标题】:Sleep() being ignored when using semaphores使用信号量时忽略 Sleep()
【发布时间】:2019-03-05 10:50:35
【问题描述】:

我正在使用信号量来同步进程。我对信号量函数的行为有些困惑(wait()signal()

我的场景:

  • 我有两个循环创建这些进程visitorkeyholder

  • 访客和钥匙持有人可以突然到达房屋(无论是 同时有几个,而有些则延迟了几秒钟 彼此随机)

所以,这是我的实现:

id=fork();
if(id==0)
{
    //create process for each visitor
    for(i=0; i<visitor; i++)
    {
        int v_id=fork();
        if(v_id==0)
        {
            wait(visitor_sem);//visitor_sem value starts at 10(10 visitors)
            visitorArrives();
            sleep(2); //this sleep works fine
        }
        else{
            wait(NULL);
        }
    }
    for(j=0; j<visitor;j++){
        wait(NULL);
    }
}
else
{
    //create process for each keyholder
    for(i=0; i<keyholder; i++)
        {
        int k_id=fork();
        if(k_id==0)
            {
            wait(key_sem); //key_sem value starts at 3 (3 keyholders)
            keyholderArrives();
            sleep(5); //this sleep is ignored for some reason
        }
    }
    for(j=0; j<keyholder;j++){
        wait(NULL);
    }
    wait(NULL);
}

我的问题:

  • sleep() 似乎只在我的子进程中做任何事情;而对父母没有影响。

  • 我应该什么时候signal()?当我尝试使用signal() 时,进程最终会无限循环(即我将signal(visitor_sem) 放在sleep(2) 之后)

【问题讨论】:

  • 请尝试缩短您的文本和代码。目前它是一堵非结构化的文本和代码墙,并不清楚您想要实现什么。我们无法在此处粘贴操作系统 101。
  • 好的,我缩短了,谢谢。我缩短了它并删除了很多我遇到的额外问题。希望它更清楚一点
  • 关于:wait(key_sem); 函数:wait() 用于等待(在父级中)子进程更改状态(通常等待子进程退出。也许您的意思是:@987654333 @
  • 函数:fork() 尝试启动子进程。但是,有 3 种返回值: 1) 0 表示父进程正在运行。代码应该检查所有三个条件并适当处理每个条件
  • 关于:*currVisitor = *currVisitor++; 这没有考虑 C 语言的优先级,似乎对++ 运算符有误解。建议:(*currVisitor)++;

标签: c synchronization fork semaphore


【解决方案1】:
//create process for each visitor
for(i=0; i<visitor; i++)
{
    int v_id=fork(); // AA
    if(v_id==0)
    {
        wait(visitor_sem);   // BB
        visitorArrives();
        sleep(2); //this sleep works fine
    }
    else{
        wait(NULL); // CC
    }
}
for(j=0; j<visitor;j++){
    wait(NULL); // DD
}

目的是在AA 创建一堆新进程。每个新创建的进程都会成为BB 的访问者。然后在我们创建所有访问者之后,我们在DD 等待他们完成。这一切都说得通。

但是CC 还等什么呢?!在AA 点调用fork 的进程需要继续循环以创建下一个访问者。它不能等待它刚刚创建的访问者在CC 结束——这就是DD 的用途!

消除CC 处的else{wait.. 代码,以便您的访问者同时运行。

【讨论】:

  • 好的,既然您指出了这一点,那就说得通了。不需要在父进程中调用wait()来防止父进程完成?
  • @METWO 您不希望父级停止在点 CC。它还有更多工作要做——创建其他访问者。当您希望父母等待孩子时,您应该只调用wait。那是DD,而不是CC
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多