如何处理线程退出的障碍

时间:2011-11-24 21:56:41

标签: c pthreads barrier

伪码:

void * thread_start(void *arg) {
    while (1) {
        /* for each column. Only run columns the thread_num
           is assigned to */
        column_count = thread_num;
        for (; column_count < dim - 1; column_count+=threads) {
             /* do thread work for data chunk */
        }

        /* barrier */
        barrier_result = pthread_barrier_wait(barrier);

        if (not_finished == 0) {
            /* finished */
            break;
            /* break while loop, end thread.
               The barrier is now broken because it is no longer
               getting called by this thread */
        }

        /* we are not finished, loop around and 
           do thread work on next data chunk */
    }
}

我遇到障碍的问题是你如何处理在其他线程之前结束的线程?

屏障意味着每个线程都必须等待每个其他线程。

有哪些技术可以确保所有线程同时结束?

我尝试继续循环但忽略了“线程工作”,但在这种情况下,所有8个线程都完成了,没有明智的方法告诉线程“你们所有人都完成了,你们现在都可以退出了”

修改

算法:

  1. 对数据段执行操作
  2. 如果线程的数据段完成终止。
  3. 屏障等待。
  4. 一个线程用一些新数据替换该数据
  5. 重复1。
  6. 编辑2:

    是否有任何优雅的方法用一个更小的屏障覆盖屏障? (不在屏障周围放置互斥体)

1 个答案:

答案 0 :(得分:0)

根据程序逻辑的本质,确保线程同时结束。如果算法要求线程在不同时间退出,则障碍不适合该具体算法的并发控制机制。

修改

您可以原子地递增“finished_count”并循环,不进行任何工作,然后参与障碍,而该数字小于障碍计数(保护读取/写入带有适当互斥锁的finished_count)。

修改 我不确定我是否理解你添加的描述,我只是根据你的原始代码写的,也许它对你有用:

int finished_count;

void * thread_start(void *arg) {
    int finished = 0;

    while (1) {

        if (finished) {
            pthread_mutex_lock (&finished_lock);
            if (finished_count == 8) {
                pthread_mutex_unlock (&finished_lock);
                break;
            }
            pthread_mutex_unlock (&finished_lock);
        } else {
            /* for each column. Only run columns the thread_num
               is assigned to */
            column_count = thread_num;
            for (; column_count < dim - 1; column_count+=threads) {
                /* do thread work for data chunk */
            }

            /* set "finished" as appropriate */

            /* Check if we have just finished.  */
            if (finished) {
                pthread_mutex_lock (&finished_lock);
                ++finished_count;
                pthread_mutex_unlock (&finished_lock);
            }
        }

        barrier_result = pthread_barrier_wait(barrier);
    }

    return 0;
}

修改

为了澄清我上面关于复制或重新初始化的评论,POSIX说:

http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_barrier_init.html

  

如果调用pthread_barrier_init()指定已初始化的障碍,则结果未定义。

  

只有barrier引用的对象可用于执行同步。在调用pthread_barrier_destroy()或pthread_barrier_wait()时引用该对象的副本的结果是未定义的。