###################################################
进程/线程 同步.(posix)
互斥锁
条件变量
读写锁
记录上锁
-----------------------------------------------------------
互斥锁:
用于上锁和解锁。保护代码临界区,保证任何时刻只有一个线程在临界区内执行。
gcc -lpthread
#include <pthread.h>
建立互斥量:
int
pthread_mutex_init(pthread_mutex_t *mutex, constpthread_mutexattr_t *mutexattr);
如果是静态分配的可以直接赋值为PTHREAD_MUTEX_INITIALIZER使用默认属性,如果是动态分配的或者分配在共享内存区中,需要调用该函数初始化。
给互斥量加锁:
int
pthread_mutex_lock(pthread_mutex_t *mutex);
如果这个线程被另外的互斥锁锁住,就阻塞。
int
pthread_mutex_trylock(pthread_mutex_t*mutex);
非阻塞版本,不等待直接返回错误。
给互斥量解锁:
int
pthread_mutex_unlock(pthread_mutex_t *mutex);
销毁互斥量:
int
pthread_mutex_destroy(pthread_mutex_t *mutex);
---------------------------------------------------
条件变量
用于等待。
gcc -lpthread
#include <pthread.h>
int pthread_cond_init(pthread_cond_t*cond, pthread_condattr_t *cond_attr);
如果是静态分配的可以直接赋值为PTHREAD_COND_INITIALIZER,使用默认属性。如果是动态分配的或者分配在共享内存区中,需要调用该函数初始化。
int pthread_cond_signal(pthread_cond_t*cond);
只唤醒等待在条件变量cond上的一个线程。
int pthread_cond_broadcast(pthread_cond_t*cond);
唤醒条件变量cond上的多个线程。
int pthread_cond_wait(pthread_cond_t*cond, pthread_mutex_t *mutex);
给互斥锁mutex解锁,把调用线程投入睡眠,直到另外某个线程就条件变量cond调用pthread_cond_signal函数;返回前重新给mutex上锁。
int pthread_cond_timedwait(pthread_cond_t*cond, pthread_mutex_t *mutex, const struct timespec *bastime);
指定了阻塞的时间。
int pthread_cond_destroy(pthread_cond_t*cond);
销毁条件变量。
---------------------------------------------------
读写锁:
将读和写分开,用于读叫共享锁,用于写叫独占锁。
#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t*restrict rwlock, const pthread_rwlockattr_t *restrict attr);
如果是静态分配的可以直接赋值为PTHREAD_RWLOCK_INITIALIZER,使用默认属性。如果是动态分配的或者分配在共享内存区中,需要调用该函数初始化。
int pthread_rwlock_rdlock(pthread_rwlock_t*rwlock);
获取一个读锁,如果没有获取到就阻塞。
int pthread_rwlock_tryrdlock(pthread_rwlock_t*rwlock);
获取一个读锁,没有获取到就返回错误。
int pthread_rwlock_wrlock(pthread_rwlock_t*rwlock);
获取一个写锁,如果没有获取到就阻塞。
int pthread_rwlock_trywrlock(pthread_rwlock_t*rwlock);
获取一个写锁,没有获取到就返回错误。
int pthread_rwlock_unlock(pthread_rwlock_t*rwlock);
解除读写锁。
int pthread_rwlock_destroy(pthread_rwlock_t*rwlock);
销毁一个读写锁。
---------------------------------------------------
互斥锁、条件变量、读写锁 的属性
XXX:mutex、cond、rwlock
int pthread_XXXattr_getpshared(constpthread_XXXattr_t *attr, int *valptr);
返回当前的属性值到valptr。
int pthread_XXXattr_setpshared(pthread_XXXattr_t*attr, int value);
将value设置给当前属性。
value取值:
PTHREAD_PROCESS_PRIVATE:不在进程间共享
PTHREAD_PROCESS_SHARED:在进程间共享
int pthread_XXXattr_init(pthread_XXXattr_t*attr);
初始化设置的属性。
int pthread_XXXattr_destroy(pthread_XXXattr_t*attr);
销毁设置的属性。
-----------------------------------------------------------
posix记录上锁:
记录上锁用于进程之间共享某个文件的读与写。
记录上锁的posix接口是fcntl函数.
#include<unistd.h>
#include<fcntl.h>
int fcntl(int fildes, int cmd, …/*arg*/);
执行各种描述符控制操作。
用于记录上锁的cmd:
F_SETLK: 获取或释放锁,如果无法将该锁授予调用过程就返回错误。
F_SETLKW: 获取或释放锁,如果无法将该锁授予调用过程就阻塞。
F_GETLK: 检查是否有某个以存在的锁妨碍即将授予新锁,将该锁信息写入flock结构。
记录上锁要求第三个参数为下面结构:
struct flock
{
short l_type; //F_RDLCK, F_WRLCK, F_UNLCK
short l_whence; //SEEK_SET, SEEK_CUR, SEEK_END
off_t l_start; // 根据l_whence解释从哪里开始偏移
off_t l_len; // 0 就是从l_start到长度的最大可能值
pid_t l_pid; // F_GETLK返回的PID
}
锁住整个文件就是:
l_whence = SEEK_SET
l_start = 0
l_len = 0
对于一个打开的某个文件的给定进程,当关闭该文件的所有描述符或它本身终止,与该文件关联的所有锁都被删除。
锁不能通过fork由子进程继承。