多线程之Barrier和Rwlock的小理论知识(五)

原创 2018年02月09日 20:39:23

1. 理论部分

1.1 Barriers

  Barriers比较重要的两个概念:

  • A barrier allows each thread to wait until all cooperating threads have reached the same point, and then continue executing from there.

  • but the threads don’t have to exit. They can continue working after all threads have reached the barrier.

#include <pthread.h>
int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned int count);
int pthread_barrier_destroy(pthread_barrier_t *barrier);
Both return: 0 if OK, error number on failure

int pthread_barrier_wait(pthread_barrier_t *barrier);
Returns: 0 or PTHREAD_BARRIER_SERIAL_THREAD if OK, error number on failure

  Barriers的使用方式中,值得关注几个小点:

  • When we initialize a barrier, we use the count argument to specify the number of threads that must reach the barrier before all of the threads will be allowed to continue

  • The thread calling pthread_barrier_wait is put to sleep if the barrier count (set in the call to pthread_barrier_init) is not yet satisfied. If the thread is the last one to call pthread_barrier_wait, thereby satisfying the barrier count, all of the threads are awakened.

  • To one arbitrary thread, it will appear as if the pthread_barrier_wait function returned a value of PTHREAD_BARRIER_SERIAL_THREAD.This allows one thread to continue as the master to act on the results of the work done by all of the other threads.

  在上一篇的记录里面,我使用了variable condition来同步主子线程,现在完全可以用barrier来达到同样的效果,并且同步效果“应”好于前者,相关的实验就不重复了。

1.2 Barriers attribute

#include <pthread.h>
int pthread_barrierattr_init(pthread_barrierattr_t *attr);
int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
Both return: 0 if OK, error number on failure

int pthread_barrierattr_getpshared(const pthread_barrierattr_t * restrict attr, int *restrict pshared);
int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared);
Both return: 0 if OK, error number on failure

The only barrier attribute currently defined is the process-shared attribute, which controls whether a barrier can be used by threads from multiple processes or only from within the process that initialized the barrier.

1.3 Reader–Writer Locks

  多个线程可以同时持有read rwlock,但是同时只有一个线程可以持有write rwlock。听起来很适合”多读,少写”的场合。当一个线程持有write rwlock,其他线程无论读和写都得等其释放锁,而当其持有read rwlock时,别的线程也可以同时获取read rwlock。此时如果别的线程希望获得write rwlock,那么也得等所有持有read rwlock的线程全部释放锁。

  但是存在一个问题:可能想获取write rwlock的线程永远没有机会得到锁,因为进行read rwlock的线程源源不断。 为了想清楚这个问题,笔者看了下MAN pthread_rwlock_trywrlock:

  • The calling thread may deadlock if at the time the pthread_rwlock_wrlock is made it holds the read-write lock (whether a read or write lock).// rwlock deadlock的场合有点特别哦!
  • Implementations may favor writers over readers to avoid writer starvation.

  只是给出了一句模棱两可的话,很是奇怪,我的猜想:read rwlock会有次数限制,超过一定次数就会阻塞接下来的read rwlock

#include <pthread.h>
#include <time.h>
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
Both return: 0 if OK, error number on failure

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
All return: 0 if OK, error number on failure

int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict tsptr);
int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict tsptr);
Both return: 0 if OK, error number on failure

  读比写频繁的场合,使用rwlock更适合,不由自主的想到上述的write rwlock被饿死的情况。不过还是简单的记着这点,并加以运用就行。

1.4 Reader–Writer attribute

#include <pthread.h>
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
Both return: 0 if OK, error number on failure

int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * restrict attr, int *restrict pshared);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
Both return: 0 if OK, error number on failure

  rwlock就一个属性:process-shared,和mutex一样决定了是否能在多个进程之间共享此锁。

2. 实验部分

题目一:

In the example code shown in Figure 11.14, what additional synchronization (if any) is necessary to allow the master thread to change the thread ID associated with a pending job? How would this affect the job_remove function?

题目二:

Apply the techniques shown in Figure 11.15 to the worker thread example (Figures 11.1 and 11.14) to implement the worker thread function. Don’t forget to update the queue_init function to initialize the condition variable and change the job_insert and job_append functions to signal the worker threads. What difficulties arise?

题目三:

What synchronization primitives would you need to implement a barrier? Provide an
implementation of the pthread_barrier_wait function.

NOTE:为了防止篇幅过长,实验部分单独记录。^ _ ^

版权声明:本文为博主原创文章,未经博主允许不得转载。

Barrier和Rwlock的小理论知识(五)

一:理论部分Barriers  Barriers比较重要的两个概念: A barrier allows each thread to wait until all cooperating t...
  • bushipeien
  • bushipeien
  • 2017年12月13日 20:53
  • 318

【C++】Android中的同步机制

在涉及多线程、多进程编程时,同步问题是不可避免的。在不同的操作系统或者项目中,都有自独特的同步手法,不过同步原理基本相同。在Android系统中,封装了几个同步类,下面来看一下这些同步类的源码是如何实...
  • iEearth
  • iEearth
  • 2016年01月15日 17:34
  • 1702

java 多线程 future 基本原理

/** * Date:2016年9月7日下午7:56:03 * Copyright (c) 2016, www.bwbroad.com All Rights Reserved. * */ p...
  • xuejianxinokok
  • xuejianxinokok
  • 2016年09月12日 22:23
  • 514

java 多线程等待与唤醒机制

java 并发编程网站 :http://ifeve.com/java-7-concurrency-cookbook/ 一: 1:JVM线程状态 NEW, RUNNABLE, BLOC...
  • baiducheng
  • baiducheng
  • 2017年12月25日 16:08
  • 60

JAVA基础学习(十二)--多线程一线程之间的通信

线程之间的通信
  • ko0491
  • ko0491
  • 2015年09月18日 16:10
  • 206

多线程之捕获异常(五)

捕获异常/** * 线程中发生异常,如果内部没有捕获,外部是无法捕获的 * 因为线程中没有抛出异常 * */ public class ThreadException { public...
  • Kincym
  • Kincym
  • 2017年09月10日 16:55
  • 152

多线程之使用信号量

引言信号量作为GCD的一部分,常用于多线程或任务间协作,当一个任务的执行过程中需要依赖另一个任务时即可使用信号量。实现原理信号量通过信号计数来实现。其使用即计数过程可分为三个部分:创建信号量、等待信号...
  • l964968324
  • l964968324
  • 2015年09月10日 18:56
  • 438

barrier and rwlock实现POSIX源码

前言 在《POSIX多线程程序设计》中,作者David R. Butenhof给我们展示了诸多实用pthread_mutex_t 和 pthread_cond_t构建的线程同步工具,我最喜欢的两个是...
  • mingspy
  • mingspy
  • 2013年02月16日 17:48
  • 1182

java多线程——线程间通信之线程等待唤醒机制

三个方法 wait() notify() notifyAll() 三个方法都使用在同步中,因为要对持有锁(又叫监控)的线程操作。 所以要使用在同步中,因为只有同步才具有锁。 为什么这些操作线...
  • u011402596
  • u011402596
  • 2015年04月10日 01:16
  • 895

Swift - 多线程实现方式(3) - Grand Central Dispatch(GCD)

1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术:(1)NSThread(2)Cocoa NSOperation(NSOperation和NSOperationQueue)...
  • offbye
  • offbye
  • 2016年02月26日 11:24
  • 2404
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:多线程之Barrier和Rwlock的小理论知识(五)
举报原因:
原因补充:

(最多只允许输入30个字)