【问题标题】:Shared counter using combining tree deadlock issue使用组合树死锁问题的共享计数器
【发布时间】:2015-04-27 02:42:32
【问题描述】:

我正在开发一个使用组合树概念的共享计数器增量应用程序。我的目标是让这个应用程序在 2^n 个内核上工作,例如 4、8、16、32 等。这个算法可能会在任何线程故障时出错。假设不会出现线程故障或非常慢的线程。

  • 两个线程在叶节点处竞争,到达的后一个线程沿树向上。
  • 到达的第一个等待,直到第二个到达层次结构并返回正确的返回值。
  • 第二个线程唤醒第一个线程
  • 每个线程都获得正确的 fetchAndAdd 值

但是这个算法有时会被锁定在 while (nodes[index].isActive == 1) 或 while(nodes[index].waiting == 1) 循环中。我看不到任何死锁的可能性,因为每个节点只有两个线程在竞争。各位大神能帮我解答一下这个问题吗?

int increment(int threadId, int index, int value) {
    int lastValue = __sync_fetch_and_add(&nodes[index].firstValue, value);
    if (index == 0) return lastValue;
    while (nodes[index].isActive == 1) {
    }
    if (lastValue == 0) {
        while(nodes[index].waiting == 1) {
        }
        nodes[index].waiting = 1;
        nodes[lindex].isActive = 0;
    } else {
        nodes[index].isActive = 1;
        nodes[index].result = increment(threadId, (index - 1)/2, nodes[index].firstValue);
            nodes[index].firstValue = 0;
            nodes[index].waiting = 0;
    }
    return nodes[index].result + lastValue;
}

【问题讨论】:

    标签: multithreading algorithm counter


    【解决方案1】:

    我认为这不适用于 1 个核心。您在 isActive 上无限循环,因为您不能将 isActive 设置为 0,除非它是 0。

    我不确定你的代码是否有阻止这种情况的机制,但是,这是我最好的破解方法 这是运行并导致问题的线程:

    例如)

    thread1                         thread 2
    nodes[10].isActive = 1
                                    //next run on index 10
                                    while (nodes[index].isActive == 1) {//here is the deadlock}
    

    很难准确理解这里发生了什么/您要做什么,但我建议您以某种方式需要能够停用节点 [index].isActive。您可能希望在函数结束时将其设置为 0

    【讨论】:

    • 你说得对,这不适用于 1 个核心。未提及的假设之一是将有 2^n 个内核。
    • 对。 N=0 对应于 1 个核心。此外,我很确定它是否不能在 1 核上运行,它不能在 1 的任何倍数上运行。这就是评论的初衷
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    相关资源
    最近更新 更多