【操作系统篇】线程的竞争与同步

互斥量(互斥锁)

pthread_mutex_t 互斥量就是一种特殊类型的对象,对它操作都只能使用函数执行。
man手册中没有,在头文件pthread.h中。
int pthread_mutex_init(pthread_mutex_t *__mutex,const pthread_mutexattr_t *__mutexattr)
功能:初始化互斥量
__mutex:被初始化的互斥量
__mutexattr:可以使用此互斥量来初始化一个样的互斥量,但也可以为空。

int pthread_mutex_destroy (pthread_mutex_t *__mutex)
功能:销毁一个互斥量

int pthread_mutex_lock (pthread_mutex_t *__mutex)
功能:对一个互斥量加锁,如果已经被锁上,则阻塞等待,直到被解锁,然后加锁成功返回。

int pthread_mutex_unlock (pthread_mutex_t *__mutex)
功能:对一个互斥量进行解锁。

pthread_mutex_trylock (pthread_mutex_t *__mutex)
功能:尝试对一个互斥量加锁

pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,const struct timespec *__restrict__abstime)
功能:定时锁,在多少时间如果不能加锁,则返回。

互斥量的使用规则:

1)、假定互斥量lock在非锁定状态下。
2)、线程1调用pthread_mutex_lock函数对lock执行加锁操作,此时会立即返回,lock呈锁定状态。
3)、线程2调用pthread_mutex_lock函数对lock执行加锁操作,此时线程2会阻塞,直到线程1调用pthread_mutext_unlock对lock进行解乐,线程2会lock再次加锁才返回。

信号量(计数)

进程间的信号量,是保护多个进程共享的一些资源,而线程的信号量(sem_t)也是。
man手册中没有,在semaphore.h头文件中。

int sem_init (sem_t *__sem, int __pshared, unsigned int __value)
功能:初始化信号量
__sem:被初始化的信号量
__pshared:0线程使用的,非0以共享内存的方式让多个进程访问(Linux不支持)。
__value:信号量的初始值

int sem_destroy (sem_t *__sem)
功能:销毁信号量

int sem_wait (sem_t *__sem);
功能:对信号量执行减一操作,不能减测阻塞。

int sem_timedwait (sem_t *__restrict__sem,const struct timespec *__restrict __abstime);
功能:对信号量执行减一操作,在多少时间如果不能加减,则返回

int sem_trywait (sem_t *__sem);
功能:对信号量尝试减一操作,能减返回0,不能减返回负1。

int sem_post (sem_t *__sem)
功能:对信号量执行加一操作。

int sem_getvalue (sem_t *__restrict __sem, int * __restrict __sval)
功能:获取信号量的值。

注意:互斥量是任何时候都只能一个线程访问共享资源(适合只有一个资源时),而信号量可以多个线程访问资源(适合保护多个资源),如果信号量初始化为1,则它与互斥量等待。

条件变量

pthread_cond_t 条件变量可以让调用线程在满足特定的条件下暂停,然后也被其它线程唤醒。

man手册没有,函数的声明在pthread.h头文件中。
int pthread_cond_init (pthread_cond_t* cond,const pthread_condattr_t* cond_attr);
功能:初始化条件变量
cond:被初始化的条件变量
cond_attr:用cond_attr初始化cond,如果为空则只初始化cond

int pthread_cond_wait(pthread_cond_t* cond,pthread_mutex_t* mutex);
功能:使用调用线程睡入cond条件变量中,并把锁mutex解开,当其它线程调用pthread_cond_signal函数时才会再次醒来,醒来时会再次加锁,如果加锁失败,则再次阻塞。

int pthread_cond_signal(pthread_cond_t *__cond)
功能:从条件变量cond从唤醒一个线程并令重新加锁(如果不再加锁则不能醒来)。

int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,struct timespec *time);
功能:使用调用线程睡入cond条件变量中,并把锁mutex解开,并且指定睡眠时间。

int pthread_cond_broadcast (pthread_cond_t* cond)
功能:唤醒条件变量中的所有线程

int pthread_cond_destroy(pthread_cond_t *__cond)
功能:销毁条件变量

生产者与消费者模型

是C/S构架常用的一处数据处理模型。
C客户端(数据的生产者)发送数据给服务器,为了让客户端及时得到反馈,服务器会先把数据存在一块缓冲区中(仓库),然后服务器从缓冲区中读取数据(消费数据)进行解析、匹配、处理、存储到(数据库中)。
在这个过程中如果生产者和消费都协调不好会造成效率低下(并不一定会出错),因此建立良好的生产者与消费模型是为了提高运行效率。

生产者与生产者之间的关系:生产者与生产者之间如果同时访问同一块缓冲区可能会造成数据覆盖,因此生产者与生产者之间应该互斥的生产数据。
消费者与消费者之间的关系:如果消费者与消费者之间同时访问一条数据可能会造成数据的重复,因此消费者与消费者之间应该互斥的消费数据。
生产者与消费者之间的关系:
如果生产者生产数据过快会被“撑死”,此时生产者应用提醒所有的消费都消费,然后生产者进行睡眠。
如果消费者消费数据过快会被“饿死”,此时消费者应该提醒所有的生产者生产,然后消费者进行睡眠。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章