首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何找到导致futex设施失败的原因?

如何找到导致futex设施失败的原因?
EN

Stack Overflow用户
提问于 2018-12-26 12:17:17
回答 2查看 3.7K关注 0票数 2

我试图同步5个进程,它们必须是从同一个父亲创建的。

我试着插入5个等待子进程结束的等待程序,但是代码从未到达D4和D5。

代码语言:javascript
运行
复制
#include <unistd.h>
#include <semaphore.h>
#include <stdlib.h>
#include <sys/wait.h>


void func1(sem_t sem1, sem_t sem2);
void func2(sem_t sem1, sem_t sem2);
void func3(sem_t sem1, sem_t sem2);
void func4(sem_t sem1, sem_t sem2);
void func5(sem_t sem1, sem_t sem2);

int main() {
    sem_t s1;
    sem_t s2;

    sem_init(&s1, 1, -1);
    sem_init(&s2, 1, -1);

    void (*arr[5])(sem_t, sem_t) = {func1, func2, func3, func4, func5};

    int pid;

    for (int i=0; i<5; i++) {
        pid = fork();
        if (pid == 0) {
            arr[i](s1, s2);
            break;
        }
    }

    return 0;
}


void func1(sem_t sem1, sem_t sem2) {
    system("echo D1");
    sem_post(&sem1);
}

void func2(sem_t sem1, sem_t sem2) {
    system("echo D2");
    sem_post(&sem1);
}

void func3(sem_t sem1, sem_t sem2) {
    system("echo D3");
    sem_post(&sem2);
}

void func4(sem_t sem1, sem_t sem2) {
    sem_wait(&sem1);
    system("echo D4");
    sem_post(&sem2);
}

void func5(sem_t sem1, sem_t sem2) {
   sem_wait(&sem2);
    system("echo D5");
}

我希望D4显示在D1和D2之后,D5显示在最后(D3中独立于D1、D2、D4)。但是我的代码从未到达D4,因为futex工具返回了一个意外的错误。

输出:

代码语言:javascript
运行
复制
The futex facility returned an unexpected error code.D1
D2
D3
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-26 13:25:26

您通过值传递信号量,这是不正确的,因为每个函数中的sem_t变量都是原始值的副本。(这就是为什么sem_init()sem_post()sem_wait()等函数都将信号量的地址作为参数。)

您需要按地址传递信号量,因此每个函数都对原始信号量进行操作:

代码语言:javascript
运行
复制
void func1(sem_t *sem1, sem_t *sem2);
void func2(sem_t *sem1, sem_t *sem2);
void func3(sem_t *sem1, sem_t *sem2);
void func4(sem_t *sem1, sem_t *sem2);
void func5(sem_t *sem1, sem_t *sem2);

代码语言:javascript
运行
复制
void (*arr[5])(sem_t *, sem_t *) = {func1, func2, func3, func4, func5};

并调用该函数如下:

代码语言:javascript
运行
复制
        arr[i](&s1, &s2);

然后,这些职能应采取以下形式:

代码语言:javascript
运行
复制
void func1(sem_t *sem1, sem_t *sem2) {
    system("echo D1");
    sem_post(sem1);
}

请注意,传递给func1()的地址直接传递给sem_post()

编辑:

正如其他人所指出的,您正在错误地初始化信号量。不能将信号量初始化为负值。

专用共享信号量

正如注释中所指出的,semphores不在多个进程之间共享的内存中。

将semphores放入共享内存的一种方法是使用mmap()

代码语言:javascript
运行
复制
#include <sys/mman.h>

int main() {
    ...
    // map a 4k page of shared memory (assumes a sem_t is small
    // enough to fit at least two)
    void *sharedMem = mmap( 0, 4 * 1024, PROT_READ | PROT_WRITE,
        MAP_SHARED | MAP_ANONYMOUS, -1, 0 );

    // use the mmap()'d memory as shared semphores
    sem_t *semArray = ( sem_t * ) sharedMem;

    // initialize the semaphores
    sem_init( &( semArray[ 0 ] ), 1, 0 );
    sem_init( &( semArray[ 1 ] ), 1, 0 );

调用代码变成

代码语言:javascript
运行
复制
    arr[i](&( semArray[ 0 ] ), &( semArray[ 1 ] ));
票数 3
EN

Stack Overflow用户

发布于 2018-12-26 13:23:22

因此,在这个代码中需要做两个小的修改。

  1. 首先,需要正确地初始化信号量。sem_init(&s1, 1, 1);而不是sem_init(&s1, 1, -1);
  2. 父进程需要等待所有子进程退出,然后才退出。因此,在程序结束之前,主程序中的wait(NULL);

代码语言:javascript
运行
复制
#include <unistd.h>
#include <semaphore.h>
#include <stdlib.h>
#include <sys/wait.h>


void func1(sem_t sem1, sem_t sem2);
void func2(sem_t sem1, sem_t sem2);
void func3(sem_t sem1, sem_t sem2);
void func4(sem_t sem1, sem_t sem2);
void func5(sem_t sem1, sem_t sem2);

int main() {
    sem_t s1;
    sem_t s2;

    sem_init(&s1, 1, 1);
    sem_init(&s2, 1, 1);

    void (*arr[5])(sem_t, sem_t) = {func1, func2, func3, func4, func5};

    pid_t child_pid, wpid;
    int status;

    for (int i=0; i<5; i++) {
        child_pid = fork();
        if (child_pid == 0) {
            arr[i](s1, s2);
            // break;
            exit(0);
        }
    }

    wait(NULL);
    // while ((wpid = wait(&status)) > 0);
    return 0;
}


void func1(sem_t sem1, sem_t sem2) {
    system("echo D1");
    sem_post(&sem1);
}

void func2(sem_t sem1, sem_t sem2) {
    system("echo D2");
    sem_post(&sem1);
}

void func3(sem_t sem1, sem_t sem2) {
    system("echo D3");
    sem_post(&sem2);
}

void func4(sem_t sem1, sem_t sem2) {
    sem_wait(&sem1);
    system("echo D4");
    sem_post(&sem2);
}

void func5(sem_t sem1, sem_t sem2) {
   sem_wait(&sem2);
    system("echo D5");
}

你可以跑到这里检查一下。单线码

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53932013

复制
相关文章

相似问题

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