多线程中的锁机制
Posted 达内首都教学部
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程中的锁机制相关的知识,希望对你有一定的参考价值。
由于多线程之间是并发执行的,而系统调度又是随机的,因此在写多线程程序时会出现很多问题,这时就免不了要用到各种锁机制来保证线程安全且按我们的意愿正确执行。
pthread_mutex_t mutex;
静态分配
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZED
动态分配
int pthread_mutex_init ( pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
#include <iostream>
#include <unistd.h>
#include <pthread.h>
using namespace std;
int piaopiao=10;
pthread_mutex_t mutex;
void *ticket(void* arg)
{
char* str=static_cast<char*>(arg);
while(1)
{
pthread_mutex_lock(&mutex);
if(piaopiao<=0)
{
pthread_mutex_unlock(&mutex);
break;
}
piaopiao--;
cout<<str<<"sale:"<<piaopiao+1<<endl;
pthread_mutex_unlock(&mutex);
usleep(10000);
}
}
int main()
{
pthread_t t1,t2,t3,t4;
pthread_mutex_init(&mutex,NULL);
pthread_create(&t1,NULL,ticket,(void*)"pthread t1");
pthread_create(&t2,NULL,ticket,(void*)"pthread t2");
pthread_create(&t3,NULL,ticket,(void*)"pthread t3");
pthread_create(&t4,NULL,ticket,(void*)"pthread t4");
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
pthread_join(t4,NULL);
pthread_mutex_destroy(&mutex);
}
void pthread_cleanup_push(void (*routine)(void *),void *arg);
void pthread_cleanup_pop(int execute);
pthread_exit()
pthread_cancel()
pthread_cleanup_pop()的参数不为0时,
且执行到这行代码时
会触发这两个函数
是以宏的方式实现的do{ }while(0) 的形式,
因此这两个函数必须成对出现。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t mutex;
void callback(void* arg)
{
printf("callback ");
sleep(1);
pthread_mutex_unlock(&mutex);
}
void* even(void* arg)
{
int i=0;
for(i=0;;i+=2)
{
pthread_cleanup_push(callback,NULL);
pthread_mutex_lock(&mutex);
printf("%d ",i);
pthread_mutex_unlock(&mutex);
pthread_cleanup_pop(0);
}
}
void* odd(void* arg)
{
int i=0;
for(i=1;;i+=2)
{
pthread_mutex_lock(&mutex);
printf("%d ",i);
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t t1,t2;
pthread_mutex_init(&mutex,NULL);
pthread_create(&t1,NULL,even,NULL);
pthread_create(&t2,NULL,odd,NULL);
sleep(2);
pthread_cancel(t1);
pthread_mutex_unlock(&mutex);//false
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_mutex_destroy(&mutex);
}
pthread_spin_t spin;
pthread_spin_init();
pthread_spin_lock();//得不到,忙等待busyloop,一直占用cpu;而互斥锁在得不到时会挂起等待,让出CPU
pthread_spin_unlock();
pthread_spin_destroy();
实际工作中用的比较少
读读共享,读写互斥,读优先级高
应用于大量读进程,少量写进程(读者写者模型)
pthread_rwlock_t rwlock;
pthread_rwlock_init(&rwlock,NULL);
pthread_rwlock_rdlock(&rwlock);/pthread_rwlock_wrlock(&rwlock);
pthread_rwlock_unlock(rwlock);
pthread_rwlock_destroy(rwlock);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int count=0;
pthread_rwlock_t rwlock;
void* route_read(void *arg)
{
int i=*(int *)arg;
free(arg);
while(1)
{
pthread_rwlock_rdlock(&rwlock);
printf("%d read %d ",i,count);
pthread_rwlock_unlock(&rwlock);
usleep(1000);
}
}
void* route_write(void *arg)
{
int i=*(int *)arg;
free(arg);
while(1)
{
pthread_rwlock_wrlock(&rwlock);
printf("%d write %d ",i,++count);
pthread_rwlock_unlock(&rwlock);
usleep(1000);
}
}
int main()
{
pthread_t id[8];
int i=0;
pthread_rwlock_init(&rwlock,NULL);
for(i=0;i<5;i++)
{
int *p=(int *)malloc(sizeof(int));
*p=i;
pthread_create(&id[i],NULL,route_read,(void *)p);
}
for(i=5;i<8;i++)
{
int *p=(int *)malloc(sizeof(int));
*p=i;
pthread_create(&id[i],NULL,route_write,(void *)p);
}
for(i=0;i<8;i++)
{
pthread_join(id[i],NULL);
}
pthread_rwlock_destroy(&rwlock);
}
悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度(悲观),因此,在整个数据处理过程中,将数据处于锁定状态。 悲观锁的实现,往往依靠数据库提供的锁机制 (也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)
乐观锁
乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。
相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。
往期文章:
以上是关于多线程中的锁机制的主要内容,如果未能解决你的问题,请参考以下文章