2

伪代码:

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。

编辑2:

有没有什么优雅的方法可以用小一号的屏障覆盖屏障?(没有在屏障周围放置互斥锁)

4

1 回答 1

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() 并指定已初始化的屏障,则结果未定义。

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

于 2011-11-24T22:07:33.067 回答