线程总结3-屏障

线程总结3-屏障

0. 屏障

屏障是用户协调多个线程并行工作的同步机制。屏障允许所有的合作线程都到达某一点,然后从该点继续执行。

1. 相关函数

1.1. 初始化

#include<pthread.h>
int pthread_barrier_init(pthread_barrier_t *restrict barrier,
                        const pthread_barrierattr_t *restrict attr, 
                        unisgned int count);
int pthread_barrier_destory(pthread_barrier_t *barrier);

count 参数设置允许所有线程继续执行之前吗,必须达到屏障的线程数目。

1.2. wait函数

int pthread_barrier_wait(pthread_barrier_t *barrier);

调用pthread_barrier_wait函数的线程在屏障计数没有达到count时,会进入休眠状态。如果该线程是最后一个调用pthread_barrier_wait的线程,就满足了屏障计数,所有线程都会被唤醒。

对于一个任意线程,pthread_barrier_wait函数返回了PTHREAD_BARRIER_SERIAL_THREAD。剩下的线程看到的返回值都是0。这使得一个线程可以作为主线程,它可以工作在其他所有线程已完成的工作结果上。

2. 例程

例程1: 老师给10个学生各自分配一个task,task难易程度不同,因此耗时也不尽相同。每个学生完成自己的task后,输出"task[i] accomplished in m minutes!"。等到所有同学都完成了各自任务,老师宣布"mission accomplished!"

#include<pthread.h>
#define NTHR 10
void* task(void *arg);

pthread_barrier_t barrier;

int main()
{
    int err, i;
    pthread_t tid;

    pthread_barrier_init(&barrier, NULL, NTHR + 1);
    for (i = 0; i < NTHR; i++) {
        err = pthread_create(&tid, NULL, task, (void*)(i));
        if (err != 0) {
            printf("create thread error!\n");
            return -1;
        }
    }
    pthread_barrier_wait(&barrier);
    printf("mission accomplished!\n");
    return 0;
}

void* task(void *arg)
{
    int i, t;

    i = (int)arg;
    t = rand() % 10 + 1;
    // 睡几秒钟,假装我们在执行任务
    sleep(t); 
    printf("task %d accomplished in %d minutes\n", i, t);
    pthread_barrier_wait(&barrier);
    return ((void*)0);
}

完整例程参见barrier-ex01.c

例程2: 对1000万个随机数进行排序。

在这个例子中,我们创建了100个线程,每个线程对10万个数字进行堆排序,排序完成后,在主线程进行合并。

int main()
{
    int err, i;
    pthread_t tid;
    printf("INT_MAX = %d\n", INT_MAX);

    srand(time(NULL));  
    for (i = 0; i < NUMNUM; i++) {
        // sleep_ms(1);
        nums[i] = rand() % INT_MAX;
    }

    // 初始化barrier
    pthread_barrier_init(&barrier, NULL, NTHR + 1);
    // 创建100个排序线程
    for (i = 0; i < NTHR; i++) {
        err = pthread_create(&tid, NULL, sort, (void*)(i * TNUM));
        if (err != 0) {
            printf("create thread error!\n");
            return -1;
        }
    }
    
    pthread_barrier_wait(&barrier);
    //合并排序结果
    merge();
    printf("-------------------------------------\n");
    for (i = 0; i < NUMNUM; i++) {
        // nums[i] = random();
        printf("%10d \n", nums[i]);
        if ((i + 1) % TNUM == 0) {
            printf("-------------------------------------\n");
        }
    }
    return 0;
}

完整例程参见barrier-ex02.c

3.参考资料

[1.] 《unix环境高级编程》第11章

全部评论

相关推荐

10-14 23:01
已编辑
中国地质大学(武汉) Java
CUG芝士圈:虽然是网上的项目,但最好还是包装一下,然后现在大部分公司都在忙校招,十月底、十一月初会好找一些。最后,boss才沟通100家,别焦虑,我去年暑假找第一段实习的时候沟通了500➕才有面试,校友加油
点赞 评论 收藏
分享
11-09 14:54
已编辑
华南农业大学 产品经理
大拿老师:这个简历,连手机号码和照片都没打码,那为什么关键要素求职职位就不写呢? 从上往下看,都没看出自己到底是产品经理的简历,还是电子硬件的简历? 这是一个大问题,当然,更大的问题是实习经历的描述是不对的 不要只是去写实习流程,陈平,怎么去开会?怎么去讨论? 面试问的是你的产品功能点,是怎么设计的?也就是要写项目的亮点,有什么功能?这个功能有什么难处?怎么去解决的? 实习流程大家都一样,没什么优势,也没有提问点,没有提问,你就不得分 另外,你要明确你投的是什么职位,如果投的是产品职位,你的项目经历写的全都是跟产品无关的,那你的简历就没用 你的面试官必然是一个资深的产品经理,他不会去问那些计算机类的编程项目 所以这种四不像的简历,在校招是大忌
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务