多线程之如何构造自己的barrier函数?(七)
2018-02-10 21:18
288 查看
1. 题目
What synchronization primitives would you need to implement a barrier? Provide an implementation of the pthread_barrier_wait function.int pthread_barrier_wait(pthread_barrier_t *barrier); Returns: 0 or PTHREAD_BARRIER_SERIAL_THREAD if OK, error number on failure
2. 审题
基于上一篇的描述,pthread_barrier_wait的特性感觉和
variable condition很像啊,所以完全可以尝试用
variabl condition来试试水:
pthread_barrier_init指定了
count数
pthread_barrier_wait的调用会使内部计数值加1,如果计数值没达到
count,则当前线程休眠。否则,唤醒全部在该函数调用处休眠的线程。
pthread_barrier_wait返回后继续执行后续的代码段,并在任意线程中返回
PTHREAD_BARRIER_SERIAL_THREAD。
3. 程序展示
3.1 设计的API展示
typedef struct { pthread_mutex_t barrier_mutex; unsigned int count; unsigned int max_count; pthread_cond_t barrier_cond; } pthread_barrier; int pthread_barrier_init_1(pthread_barrier *restrict barrier, unsigned int count) { if ( pthread_mutex_init(&barrier->barrier_mutex,NULL) != 0) return -1; if ( pthread_cond_init(&barrier->barrier_cond,NULL) != 0) return -1; barrier->max_count=count; barrier->count=0; return 0; } int pthread_barrier_wait_1(pthread_barrier *barrier) { pthread_mutex_lock(&barrier->barrier_mutex); barrier->count++; if(barrier->count < barrier->max_count) { pthread_cond_wait(&barrier->barrier_cond,&barrier->barrier_mutex); pthread_mutex_unlock(&barrier->barrier_mutex); } else { pthread_cond_broadcast(&barrier->barrier_cond); pthread_mutex_unlock(&barrier->barrier_mutex); return PTHREAD_BARRIER_SERIAL_THREAD; } return 0; }
3.2 应用该API
其中用到了variable-condition,现在我们用上面自己构造
pthread_barrier的替换掉其中使用的
variable condition看看运行效果如何。
[root@localhost ~]# diff -Naur 11_4.c 11_8.c --- 11_4.c 2018-02-09 17:48:17.463201599 +0800 +++ 11_8.c 2018-02-10 21:15:02.094194080 +0800 @@ -12,10 +12,47 @@ struct foo * f_next; }; +typedef struct { + pthread_mutex_t barrier_mutex; + unsigned int count; + unsigned int max_count; + pthread_cond_t barrier_cond; +} pthread_barrier; + struct foo *fh[NHASH]; pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t hashr_mutex = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t hashr_cond = PTHREAD_COND_INITIALIZER; +pthread_barrier barrier; + + + +int pthread_barrier_init_1(pthread_barrier *restrict barrier, unsigned int count) +{ + if ( pthread_mutex_init(&barrier->barrier_mutex,NULL) != 0) + return -1; + if ( pthread_cond_init(&barrier->barrier_cond,NULL) != 0) + return -1; + barrier->max_count=count; + barrier->count=0; + return 0; +} + +int pthread_barrier_wait_1(pthread_barrier *barrier) +{ + pthread_mutex_lock(&barrier->barrier_mutex); + barrier->count++; + if(barrier->count < barrier->max_count) + { + pthread_cond_wait(&barrier->barrier_cond,&barrier->barrier_mutex); + pthread_mutex_unlock(&barrier->barrier_mutex); + } + else + { + pthread_cond_broadcast(&barrier->barrier_cond); + pthread_mutex_unlock(&barrier->barrier_mutex); + return PTHREAD_BARRIER_SERIAL_THREAD; + } + return 0; +} void foo_printf(struct foo * a) { @@ -68,7 +105,7 @@ } else { - fp1=fh[HASH(id)]; + fp1=fh[HASH(id)]; while (fp1->f_next != fp) fp1 = fp1->f_next; fp1->f_next = fp->f_next; @@ -93,13 +130,11 @@ } else { - pthread_mutex_lock(&hashr_mutex); - pthread_cond_wait(&hashr_cond,&hashr_mutex); + pthread_barrier_wait_1(&barrier); if(foo_rele((int)arg) != 0) { errx(1,"error in release the foo of the id : %d",(int)arg); } - pthread_mutex_unlock(&hashr_mutex); return((void *)0); } } @@ -124,6 +159,10 @@ int done[3]={4,4,4}; pthread_t tid; char i=0; + if(pthread_barrier_init_1(&barrier,NHASH+1) != 0) + { + errx(1,"error in initing barrier\n"); + } for( num=0;num<NHASH;num++) { err = pthread_create(&tid, 4000 NULL, thr_fn,(void *)(num*NHASH)); @@ -140,10 +179,8 @@ done[i++]=num; if(i>=NHASH) { - pthread_mutex_lock(&hashr_mutex); - pthread_cond_broadcast(&hashr_cond); - pthread_mutex_unlock(&hashr_mutex); - exit(0); + pthread_barrier_wait_1(&barrier); + exit(0); } } }
四:结果分析
[root@localhost ~]# ./11_8 thread 139879873591040, foo_id:3 thread 139879890442048, foo_id:3 thread 139879881983744, foo_id:0 thread 139879890442048, foo_id:0 thread 139879865198336, foo_id:6 thread 139879890442048, foo_id:6
很好的完成了任务,其实这也是理所当然的,笔者用
variable condition实现的
barrier,所以换汤不换药,自然和上一次实验结果相同。就不过多赘述,如果您对以上内容有所质疑,请及时指正笔者!
相关文章推荐
- javascript 中没有直接删除数组元素的函数 通过自己构造
- C#多线程函数如何传参数和返回值
- Linux 多线程应用中如何编写安全的信号处理函数
- Linux下多线程程序崩溃时如何提取出所有线程的函数调用栈(二)
- Net如何继承IDisposable接口,实现自己的Dispose()函数
- Linux 多线程应用中如何编写安全的信号处理函数
- 已知随机数函数rand7(),如何构造rand10()函数
- [MSSQL] 如何自己定义函数(返回多变量)
- Linux 多线程应用中如何编写安全的信号处理函数
- Linux 多线程应用中如何编写安全的信号处理函数
- VC多线程中全局函数如何调用对话框类成员变量及成员函数
- 谈自己对如何构造网络引擎粗浅的看法
- sort/map/unordered_map自定义类型如何构造比较函数
- TTCN3新执行器系列-如何最小化类的成员函数(对拷贝构造和赋值操作函数的反思)
- 【多线程】控制多线程并发的函数的阻塞功能如何实现?
- R语言——如何调用自己写的函数
- 如何使用composer的autoload来自动加载自己编写的函数库与类库
- C#多线程函数如何传参数和返回值
- 如何调用自己写的python函数?
- 如何根据可以产生1-5随机数的函数自己产生1-7的随机数?