1、基础知识。函数
1:线程同步机制:互斥量,读写锁,条件变量,自旋锁,屏障。spa
1,互斥量:每一个进程访问被互斥量保护的资源时,都须要先对互斥量进行判断。操作系统
1)互斥量重要属性:进程共享属性,健壮属性,类型属性。线程
2)部分系统 不支持 进程共享属性rest
3)对互斥量重复加锁会致使死锁。code
2,读写锁。blog
1)读写锁有3种状态:读模式加锁,写模式加锁,未加锁。递归
1-写加锁模式:任何加锁都会被阻塞。队列
2-读加锁模式:读模式加锁的任何线程均可以获得访问权,同时添加一个读模式锁。但,写模式加锁会被阻塞。进程
3-在读模式下,线程试图写加锁,会阻塞:1 线程自己 和 2 以后的读模式。保证写模式不会被一指阻塞。
2)递归锁可能很难处理,只有在无其余反感时,才考虑。
3)读写锁支持的惟一属性时:进程共享属性。
3,条件变量:条件变量是线程的另一种同步机制。它自己由互斥量保护。线程在改变条件状态以前必须首先锁住互斥量。
1)条件变量支持属性:进程共享属性 和 时钟属性。
4,自旋锁。
1)和互斥量相似。不一样点在于:获取锁以前,线程一直处于 忙等(自旋)阻塞状态。(互斥量使用休眠阻塞)
2)只能用于:锁持有时间短,线程不喜欢在从新调度上花费太多成本。
3)在非抢占式内核中很是有用:由于它会阻塞中断。这样中断处理程序就不会让系统陷入死锁状态。
5,屏障。
1)相似于里程碑:用户协调多个线程并行工做的同步机制。它容许每一个线程等待,直到全部合做的线程都到达某一个点(里程碑)。
2)屏障属性只有 进程共享属性。
3)PTHREAD_PROCESS_SHARED(多进程共享) 和 PTHREAD_PROCESS_PROVATE(单进程,不共享)
2、相关函数。
1:信号。
1 发送信号 int kill(pid_t pid, int signo ); 发送信号给进程/进程组 // 1 参数pid:>0 ID=pid的进程中;0 同进程组的全部进程;<0 进程组ID==pid绝对值 的进程组中;-1 全部可以发送的进程。 int raise( int signo ); 发送信号给自身。 2 信号集处理函数 int sigemptyset( sigset_t *set ); int sigfillset( sigset_t *set ); int sigaddset( sigset_t *set, int signo ); int sigdelset( sigset_t *set, int signo ); int sigismember( sigset_t *set, int signo ); 3 信号屏蔽字。 int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); // 检测和更改,或同时检测+更改进程的信号屏蔽字。 int sigpending( sigset_t *set ); // 返回一个信号集。 int sigaction( int signo, const struct sigaction *restrict act, struct sigaction *restrict oact ); // 检测/修改与指定信号相关联的处理动做 int sigsupend( const sigset_t *sigmask ); // 做用:经过参数设置信号屏蔽字。 4 信号跳转函数。 int sigsetjmp( sigjmp_buf env, int savemask ); // 设置信号跳转点。 void siglongjmp( sigjmp_buf env, int val ); // 执行跳转操做,参数val为跳转点返回值。 5 异常终止函数。 void abort( void ); // 使程序异常终止。 // 1 使用此函数,会将SIGABRT信号发送给调用进程。进程不能忽略此信号 // 2 发送SIGABRT信号,进程能够先执行清理操做,而后再终止进程。 6 线程休眠函数。 unsigned int sleep( unsigned int seconds ); int nanosleep( const struct timespec *reqtp, struct timespec *remtp ); // 提供纳妙级精度。 int clock_nanosleep( clockid_t clock_id, int flags, const struct timespec *reqtp, struct timespec *remtp ); // 多系统时钟状况下,使用相对于特定时钟的延迟时间来挂起调用进程。 int sigqueue( pid_t pid, int signo, const union sigval value ); // 信号队列,能够将信号发送到一个进程的信号队列中。部分操做系统支持此功能。 // 1 可能使休眠终止的情形:调用进程捕捉到一个信号并从信号处理程序返回。
2:互斥量。
1 初始化。 PTHREAD_MUTEX_INITIALIZER //静态分配方式。 int pthread_mutex_init( pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr ); // 动态分配内存方式 // 1 使用默认初始化,参数attr设置为NULL。 2 类析构函数(释放内存前当用)。 int pthread_mutex_destroy( pthread_mutex_t *mutex ); 3 加锁,尝试性加锁,超时锁,解锁 int pthread_mutex_lock( pthread_mutex_t *mutex ); // 若是已经加锁的互斥量,会阻塞线程,直到互斥量解锁。 int pthread_mutex_trylock( pthread_mutex_t *mutex ); //trylock尝试上锁失败后,会返回EBUSY。而不会阻塞。 int pthread_mutex_timedlock( pthread_mutex_t *restrict mutex, const struct timespec *restrict tsptr ); //超时返回:ETIMEDOUT int pthread_mutex_unlock( pthread_mutex_t *mutex ); // 1 若是线程试图对同一互斥量加锁两次,则线程会陷入死锁状态。。 // 2 超时锁参数tsptr 表示是 绝对时间(即具体时间点,而不是时间段)
3:互斥量属性相关函数。
1 初始化和类析构函数。 int pthread_mutexattr_init( pthread_mutexattr_t *attr ); int pthread_mutexattr_destroy( pthread_mutexattr_t *attr ); 2 获取/设置 进程共享属性。 int pthread_mutexattr_getshared( const pthread_mutexattr_t *restrict attr, int *restrict pshared ); int pthread_mutexattr_setshared( pthread_mutexattr_t *attr, int *pshared ); 3 获取/设置 健壮属性 int pthread_mutexattr_getrobust( const pthread_mutexattr_t *restrict attr, int *restrict robust ); int pthread_mutexattr_setrobust( pthread_mutexattr_t *attr, int *robust ); 4 解锁前,使属性状态统一。 int pthread_mutexattr_consistent( pthead_mutex_t *mutex ); 5 获取/设置 类型属性 int pthread_mutexattr_gettype( const pthread_mutexattr_t *restrict attr, int *restrict type ); int pthread_mutexattr_settype( pthread_mutexattr_t *attr, int *type );
4:读写锁
1 初始化。 int pthread_rwlock_init( pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr ); // 1 使用默认初始化,参数attr设置为NULL。 2 类析构函数(释放内存前当用)。 int pthread_rwlock_destroy( pthread_rwlock_t *rwlock ); 3 读加锁,尝试读,超时版读,写加锁,尝试写,超时版写,解锁。 int pthread_rwlock_rdlock( pthread_rwlock_t *rwlock ); int pthread_rwlock_tryrdlock( pthread_rwlock_t *rwlock ); int pthread_rwlock_timedrdlock( pthread_rwlock_t *rwlock, const struct timespec *restrict tsptr ); int pthread_rwlock_wrlock( pthread_rwlock_t *rwlock ); int pthread_rwlock_trywrlock( pthread_rwlock_t *rwlock ); int pthread_rwlock_timedwrlock( pthread_rwlock_t *rwlock, const struct timespec *restrict tsptr ); int pthread_rwlock_unlock( pthread_rwlock_t *rwlock ); // 1 读加锁有次数限制。 // 2 尝试版本,出错返回:EBUSY。 // 3 超时版本,出错返回:ETIMEDOUT。超时时间 为 绝对时间。 4 获取/设置 进程共享属性。 int pthread_rwlockattr_getpshared( const pthread_rwlockattr_t *restrict attr, int *restrict pshared ); int pthread_rwlockattr_setpshared( pthread_rwlockattr_t *attr, int *pshared );
5:条件变量。
1 初始化。 int pthread_cond_init( pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr ); // 1 使用默认初始化,参数attr设置为NULL。 2 类析构函数(释放内存前当用)。 int pthread_cond_destroy( pthread_cond_t *cond ); 3 等待条件为真,超时版本。 int pthread_cond_wait( pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex ); //此函数能够保证线程必定能够进入条件等待队列中。 int pthread_cond_timedwait( pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict tsptr ); // 1 将加锁互斥量传入,而后将调用线程放入条件队列中,再解锁互斥量。等wait函数返回后,互斥量再加锁。 // 2 超时返回:ETIMEDOUT 4 唤醒等待条件的线程。 int pthread_cond_signal( pthread_cond_t *cond ); // 最少唤醒一个线程。 int pthread_cond_broadcast( pthread_cond_t *cond ); // 唤醒所有线程。 // 1 须要注意:要等条件状态改变之后,在使用这两个函数!!! 5 条件属性的初始化和类析构函数。 int pthread_condattr_init( pthread_condattr_t *attr ); int pthread_condattr_destroy( pthread_condattr_t *attr ); 6 获取/设置 进程共享属性。 int pthread_condattr_getpshared( const pthread_condattr_t *restrict attr, int *restrict pshared ); int pthread_condattr_setpshared( pthread_condattr_t *attr, int *pshared ); 7 获取/设置 时钟属性。 int pthread_condattr_getclock( const pthread_condattr_t *restrict attr, clockid)t *restrict clock_id ); int pthread_condattr_setclock( pthread_condattr_t *attr, clockid)t *clock_id );
6:自旋锁。
1 初始化,类析构函数(释放内存前使用) int pthread_spin_init( pthread_spinlock_t *lock, int pshared ); int pthread_spin_destroy( pthread_spinlock_t *lock ); 2 加锁,尝试性加锁,解锁。 int pthread_spin_lock( pthread_spinlock_t *lock ); int pthread_spin_trylock( pthread_spinlock_t *lock ); int pthread_spin_unlock( pthread_spinlock_t *lock );
7:屏障。
1 初始化,类析构函数(释放内存前使用) 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 ); // 1 参数count表示须要多少个线程达到此节点后,才能够继续运行。count设置后不会改变。 2 当前线程已完成,等待其余线程。 int pthread_barrier_wait( pthread_barrier_t *barrier ); // 如未知足count数,则此线程进行休眠。 3 初始化 和 类析构函数。 int pthread_barrierattr_init( pthread_barrierattr_t *attr ); int pthread_barrierattr_destroy( pthread_barrierattr_t *attr ); 4 获取/设置 进程共享属性。 int pthread_barrierattr_getpshared( const pthread_barrierattr *restrict attr, int *restrict pshared ); int pthread_barrierattr_setpshared( pthread_barrierattr *attr, int pshared );
3、