futex 工具返回了意外的错误代码并已中止

Posted

技术标签:

【中文标题】futex 工具返回了意外的错误代码并已中止【英文标题】:The futex facility returned an unexpected error code and Aborted 【发布时间】:2018-07-20 17:03:51 【问题描述】:

我正在尝试使用信号量解决哲学家就餐问题。 哲学家先拿起左叉子,然后拿起右叉子,吃完后放下。 我正在使用 5 个线程来实现这一点,每个线程一个用于每个哲学家,5 个信号量一个用于每个筷子。 需要由父节点执行死锁检查,如果发现则打破死锁。 当我只运行哲学家思考和饮食的循环时,程序会因错误而崩溃 The futex facility returned an unexpected error code.Aborted。 我没有得到任何有关如何调试此错误的信息。

哲学家的线索如下

void *Philospoher_behaviour(void *param)
int id  = *(int *)param; // assigns a ID to the Phil
int state; // hungry , thinking, eating
// first the philopher thinks
while(1) 
    state = THINKING;
    float time = (float)rand()/RAND_MAX;
    printf("Philosopher %d starts THINKING for %f\n",id,time);
    sleep(time);
    // the phil goes hungrg
    state = HUNGRY;
    printf("Philosopher %d is now HUNGRY\n",id);
    // first wait for left
    sem_wait(&chopsticks[id]);
    printf("Philosopher %d grabs chopstick %d to this LEFT\n",id,id);

    // got left chopstick
    sem_wait(&chopsticks[(id+1)%5]);
    printf("Philosopher %d grabs chopstick %d to this RIGHT\n",id,(id+1)%5);

    // got the right chopstick
    state = EATING;
    time = (float)rand()/RAND_MAX;
    printf("Philosopher %d starts EATING for time  %f\n",id,time);

    sleep(time);

    sem_post(&chopsticks[(id + 1)%5]);
    printf("Philosopher %d releases chopstick %d to this RIGHT\n",id,(id+1)%5);
    sem_post(&chopsticks[id]);
    printf("Philosopher %d releases chopstick %d to this LEFT\n",id,(id));
    state = THINKING;

    time = (float)rand()/RAND_MAX;
    sleep(time);


主程序如下

sem_t chopsticks[5];// five chopsticks as a resource
pthread_t philosopher[5]; //five philosoophers

int main()
srand(time(NULL));
for ( int i=0 ;i <5;i++)
    sem_init(&chopsticks[i], 0, 1); // local to the threads with initial value of 1


// now create the indiviual threads
for(int i=0;i<5;i++)
    if( pthread_create(&philosopher[i],NULL, Philospoher_behaviour ,&i) != 0)  // create thread one
        printf("Cant create thread %d\n",i);
        return 1;
    
    else
        printf("Creadted Philosopher Number : %d\n",i);
    


for(int i=0;i<5;i++)
    pthread_join(philosopher[i],NULL);



如何调试此错误。 我也在粘贴一次运行的输出

Creadted Philosopher Number : 0
Philosopher 1 starts THINKING for 0.483853
Creadted Philosopher Number : 1
Philosopher 1 starts THINKING for 0.059081
Creadted Philosopher Number : 2
Philosopher 3 starts THINKING for 0.149168
Creadted Philosopher Number : 3
Philosopher 4 starts THINKING for 0.073436
Creadted Philosopher Number : 4
Philosopher 5 starts THINKING for 0.833351
Philosopher 5 is now HUNGRY
Philosopher 1 is now HUNGRY
Philosopher 5 grabs chopstick 5 to this LEFT
Philosopher 1 grabs chopstick 1 to this LEFT
Philosopher 1 grabs chopstick 2 to this RIGHT
Philosopher 1 starts EATING for time  0.147257
Philosopher 3 is now HUNGRY
Philosopher 3 grabs chopstick 3 to this LEFT
Philosopher 3 grabs chopstick 4 to this RIGHT
Philosopher 1 is now HUNGRY
Philosopher 3 starts EATING for time  0.572829
Philosopher 4 is now HUNGRY
Philosopher 1 releases chopstick 2 to this RIGHT
Philosopher 1 releases chopstick 1 to this LEFT
Philosopher 5 grabs chopstick 1 to this RIGHT
Philosopher 5 starts EATING for time  0.857843
Philosopher 3 releases chopstick 4 to this RIGHT
Philosopher 3 releases chopstick 3 to this LEFT
Philosopher 4 grabs chopstick 4 to this LEFT
Philosopher 4 grabs chopstick 0 to this RIGHT
Philosopher 4 starts EATING for time  0.783497
Philosopher 1 starts THINKING for 0.308573
Philosopher 5 releases chopstick 1 to this RIGHT
Philosopher 4 releases chopstick 0 to this RIGHT
Philosopher 4 releases chopstick 4 to this LEFT
Philosopher 1 grabs chopstick 1 to this LEFT
Philosopher 3 starts THINKING for 0.086635
Philosopher 1 grabs chopstick 2 to this RIGHT
Philosopher 1 starts EATING for time  0.015005
The futex facility returned an unexpected error code.Aborted

还有一个问题,如您所见,哲学家 0 和 2 没有互动,为什么会发生这种情况。

在 GDB 中运行它我得到了这个信息

Thread 6 "part22" received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff57eb700 (LWP 12247)]
0x00007ffff7825428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
54  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.

【问题讨论】:

您的错误之一是您没有捕获sem_ 函数的返回。除了理论书籍可能建议的以外,这些都是可以(并且将会!)被中断的低级工具,例如,如果您的进程收到 IO。基本上它们不是学习并行性的正确工具,因为它们太复杂而无法正确使用。如果必须这样做(这看起来像一个作业),则必须将 sem_wait 包装在一个循环中,处理所有可能的错误,如果遇到过渡错误,请重试。 【参考方案1】:

您将main() 循环变量i 的地址传递给每个线程:

pthread_create(&philosopher[i],NULL, Philospoher_behaviour ,&i)

当你的线程执行时

int id  = *(int *)param;

i 中的值可能已更改。

【讨论】:

好的,我已经通过使用数字数组(即id[5] = 0,1,2,3,4 并传递&amp;id[i])来改变它。这就是这个错误的原因。

以上是关于futex 工具返回了意外的错误代码并已中止的主要内容,如果未能解决你的问题,请参考以下文章

启动 Intel python3.7 shell 时出现意外错误:无法执行任何命令 - 中止错误

8个用来取消或中止 Windows 关闭/重启的工具

错误:分配:无法签入命名的 futex 名称 = jack_sem.system 错误 = 权限被拒绝

为啥我收到错误“中止 loadExtensionAsync”

setSinkId() 函数在 Electron App 中抛出错误

REST API 错误代码 500 处理