进程间通信学习笔记-互斥锁 && 读写锁

第七章 互斥锁和条件变量

互斥锁是用于保护临界区的,实际上是保护在临界区中被操纵的数据,保护多个线程或者多个进程的共享数据。

#include
int pthread_mutex_lock(pthread_mutex_t *mptr);
int pthread_mutex_trylock(pthread_mutex_t *mptr);
int pthread_mutex_unlock(pthread_mutex_t *mptr);

如果互斥锁已被其他线程占据了,那么pthread_mutex_lock将阻塞直到互斥锁被解锁。第二个函数在这种情况下,会返回一个EBUSY错误。

如果互斥锁是静态分配 的,可以用PTHREAD_MUTEX_INITIALIZER初始化为常量。如果互斥锁是动态分配的,就要用pthread_mutex_init()函数初始化。

对比上锁与等待
这个例子中,所有生产者线程都启动后,立即启动消费者线程。所以对消费者进行了改动,要判断当前消费的i是否已经生产好了。每次对共享数据进行访问时,都要申请互斥锁。

条件变量:等待与信号发送
互斥锁用于上锁,条件变量用于等待

#include
int pthread_cond_wait(pthread_cond_t *cptr,pthread_mutex_t *mptr);
int pthread_cond_signal(pthread_cond_t *cptr);

pthread_cond_wait等待某个条件为真时。这个函数原子地执行以下两步:

  • 给互斥锁解锁
  • 把调用线程投入睡眠,知道另外其某个线程就本条件变量调用pthread_cond_signal函数

然后在这个函数返回前,对互斥锁进行上锁,修改共享数据,然后对互斥锁进行解锁

7.6 条件变量:定时等待和广播
单播和广播,根据满足条件后,要唤醒因为此条件而阻塞所有线程,还是一个等待线程而采用广播和单播发送。

#include
int pthread_cond_broadcast(pthread_cond_t *cptr);
int pthread_cond_timedwait(pthread_cond_t *cptr,pthread_mutex_t *mptr, const struct timespec *abstime);

pthread_cond_timedwait函数线程就阻塞时间设置一个限制值。如果发生超时,就返回ETIMEDOUT错误
时间值是绝对时间

7.7 互斥锁和条件变量的属性

#include
int pthread_mutex_init(pthread_mutex_t *mptr, const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mptr);
int pthread_cond_init(pthread_cond_t *cptr,pthread_condattr_t *attr);
int pthread_cond_destroy(pthread_cond_t *cptr);

互斥变量和条件变量用以上函数进行初始化和摧毁

#include
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
int pthread_condattr_destroy(pthread_condattr_t *attr);

以上函数是对互斥锁、条件变量的属性进行初始化和摧毁

第八章 读写锁

读写锁的分配规则:

  • 没有线程持有某个给定的读写锁用于写,就可以有任意数目的线程持有读写锁用于读
  • 仅当没有线程持有某个给定的读写锁用于读或用于学,才能分配这个读写锁用于写

    这种对于给定资源的共享访问称为共享-独占上锁。对于读是共享锁,对于写是独占锁

#include
int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_unlock(pthread_rwlock_t *rwptr);

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);

int pthread_rwlock_init(pthread_rwlock_t *rwptr,const pthread_rwlockattr_t *attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwptr);

int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);

线程取消

#include
int pthread_cancel(pthraed_t pid);

void pthread_cleanup_push(void (*func)(void*),void *arg);
void pthread_cleanup_pop(int execute);

通过由对方调用函数pthread_cancel,一个线程可以被同一个进程内的任何其他线程所取消(cancel)
清理处理晨旭可以恢复任何需要恢复的状态。push函数中func参数是调用线程被取消是所调用的函数的地址。pop函数是删除调用线程的取消清理栈中位于在山顶的函数中的execute参数不为0时,就是调用这个函数、

你可能感兴趣的:(Linux)