当前位置: 首页 > 知识库问答 >
问题:

一个进程占用信号量

方祺
2023-03-14
if ((sem1 = sem_open(request->mem_group.sem_name, O_CREAT, 0644, 0)) ==
        SEM_FAILED) {
        perror("sem_open");
        goto finish;
        }

cache = simplecache_get(request->file_path);
    *(int *)mem_shared = cache == -1 ? -1 : 1;
    sem_post(sem);
    sem_wait(sem);
    if (cache == -1) {
        break;


        fprintf(stdout, "File was not found, going to finish\n");
    }


    file_length = lseek(cache, 0, SEEK_END);
    lseek(cache, 0, SEEK_SET);
    *(size_t *)mem_shared = file_length;

    sem_post(sem);
    sem_wait(sem1);

    if (!file_len) {
        goto finish;
    }

    bytes_transferred = 0;
    while (bytes_transferred < file_len) {

                //rest of while loop here which transfers file

这是进程2中的代码块,它应该捕捉信号量,但没有

sem_wait(sem1);

file_size = *(size_t *)mem_shared;

gfs_sendheader(ctx, GF_OK, file_size);

sem_post(sem1);

if (!file_size) {
    fprintf(stderr, "File is empty. Go to finish");
    break;
}

因此,这个想法是--这个进程2应该在另一个进程的post/wait之间获得seemaphore--此时,共享的mem段中有数据,并且不是空的。然而,相反,它在另一个进程的最后捕获信号量,这时它已经清空了sahred内存段并删除了其中的任何数据。

我做了很多问题解决,并确认a)每个进程中的信号量都是相同的信号量b)进程1在某个时候会增加信号量,然后捕获相同的信号量并减少它(用sem_getvalue检查这一点)

在这个问题上已经坚持了48小时,感到非常气馁。任何关于如何更有策略地调试它的提示或建议也将不胜感激。

共有1个答案

刘星火
2023-03-14

这说不通:

sem_post(sem);
sem_wait(sem1);

先递增信号量,然后立即递减信号量。存在争用条件,在这种情况下,您的任何一个进程都可以通过等待(因为post)获得成功,但由于该进程已经在CPU上,因此它可能总是获胜。

通常,一个进程将发布,另一个进程将等待。然后,第一个进程继续进行,如果第二个进程有更多的工作,它可以再次发布,第二个进程将根据需要等待。如果这两个进程需要协调它们的操作(即第一个进程暂停,直到第二个进程表示可以执行),那么您将使用第二个信号量,在这个信号量中,第一个进程始终等待,第二个进程发布。因此,一个特定的进程只在特定的信号量上等待或发布,而不是两者兼而有之。

 类似资料:
  • 进程的管理主要是指进程的关闭与重启。我们一般关闭或重启软件,都是关闭或重启它的程序,而不是直接操作进程的。比如,要重启 apache 服务,一般使用命令"service httpd restart"重启 apache的程序。 那么,可以通过直接管理进程来关闭或重启 apache 吗?答案是肯定的,这时就要依赖进程的 信号(Signal)了。我们需要给予该进程号,告诉进程我们想要让它做什么。 系统中

  • 问题内容: 我有两个共享库链接到我的测试应用程序。这两个库都具有的信号处理程序。 同一信号具有多个信号处理程序是否有效?生成信号时,处理程序将执行哪个顺序? 问题答案: 正如其他人所说,只能设置一个信号处理程序,这是最后一个。然后,您将不得不自己管理调用两个函数。该函数可以返回以前安装的信号处理程序,您可以自己调用该信号处理程序。 这样的东西(未经测试的代码):

  • 据我所知,线程可以释放信号量,而无需首先使用WaitOne获取锁。 所以,如果我们有线程A、B和C以及一个信号量,A和B调用WaitOne,得到一个锁,然后开始做他们的工作<线程C出现了,只需在信号量上调用Release。 这应该将信号量的计数增加1。这是否意味着信号量将终止A或B,或者只允许第三个线程获取锁并在其池中有3个线程,即使最大值为2?

  • 我必须分叉两个子进程,其中SIGINT命令被阻塞,但其中一个在接收到SIGTERM信号时应该解除阻塞,而另一个子进程和父进程都会打印它们的PID,作为相同SIGTERM信号的结果。第二个子进程应立即终止,但父进程应等待其子进程结束,然后停止。 我刚开始在Linux中学习C编程,但我并不真正理解分叉和信号是如何工作的。据我所知,我编写的这段代码将派生一个进程,子进程将阻止Ctrl-C命令,整个过程将

  • 上一篇尬聊了通篇的 pcntl_wait() 和 pcntl_waitpid(),就是为了解决僵尸进程的问题,但最后看起来还是有一些遗留问题,而且因为嘴欠在上篇文章的结尾出也给了解决方案:信号。 信号是一种软件中断,也是一种非常典型的异步事件处理方式。在 nix 系统诞生的混沌之初,信号的定义是比较混乱的,而且最关键是不可靠,这是一个很严重的问题。所以在后来的POSIX标准中,对信号做了标准化同时