互斥锁
使用mutex(互斥量)一般步骤
1.pthread_mutex_t mutex;创建锁
2.pthread_mutex_init:初始化
3.pthread_mutex_lock:加锁
4访问共享数据(stdout)
5.pthread_mutex_unlock:解锁
6.pthread_mutex_destroy:销毁锁
#include
#include
#include
#include
#include
//pthread_mutex_t 互斥锁类型名,
pthread_mutex_t mutex;//定义另一个互斥锁变量mutex,全局变量,所有线程可以共享使用
void *tfn2(void *arg)
{//当某个线程,不进行对共享资源进行加锁操作时,仍旧会造成抢夺资源现象
srand(time(NULL));
while(1)
{
int ret=pthread_mutex_trylock(&mutex);
if(ret!=0)
{
printf("pthread_mutx_trylock err:%s\n",strerror(ret));
}
else
{
printf("---tfn2()---print ");
sleep(rand() % 3);
printf("to stdout\n");
sleep(rand() % 3);
ret=pthread_mutex_unlock(&mutex);//解锁
if(ret!=0)
{
fprintf(stderr,"pthread_mutex_unlock() error:%s\n",strerror(ret));
}
}
printf("common tfn2()------\n");
sleep(rand() % 3);
}
}
void *tfn(void *arg)
{
srand(time(NULL));
while (1)
{
int ret=pthread_mutex_lock(&mutex);//加锁
if(ret!=0)
{
fprintf(stderr,"pthread_mutex_lock() error:%s\n",strerror(ret));
}
printf("hello ");
sleep(rand() % 3);
printf("world\n");
//pthread_mutex_unlock(),对加锁成功的共享资源进行解锁
ret=pthread_mutex_unlock(&mutex);//解锁
if(ret!=0)
{
fprintf(stderr,"pthread_mutex_unlock() error:%s\n",strerror(ret));
}
sleep(rand() % 3);
}
return NULL;
}
int main(void)
{
pthread_t tid;
srand(time(NULL));
//pthread_mutex_init()初始化 互斥锁
int ret=pthread_mutex_init(&mutex,NULL);//初始化锁
if(ret!=0)
{
fprintf(stderr,"mutex init error:%s\n",strerror(ret));
}
//pthread_create() 创建线程1
ret=pthread_create(&tid, NULL, tfn, NULL);
if(ret!=0)
{
fprintf(stderr,"pthread_create error:%s\n",strerror(ret));
}
//pthread_create() 创建线程2
ret=pthread_create(&tid, NULL, tfn2, NULL);
if(ret!=0)
{
fprintf(stderr,"pthread_create error:%s\n",strerror(ret));
}
while (1)
{ //pthread_mutex_lock()给已初始化过的互斥锁变量,(站在当前线程角度)对共享资源进行加锁操作
//如果加锁失败,则阻塞,也就是一直等待
ret=pthread_mutex_lock(&mutex);//加锁
if(ret!=0)
{
fprintf(stderr,"pthread_mutex_lock() error:%s\n",strerror(ret));
}
printf("HELLO ");
sleep(rand() % 3);
printf("WORLD\n");
//pthread_mutex_unlock(),对加锁成功的共享资源进行解锁
ret=pthread_mutex_unlock(&mutex);//解锁
if(ret!=0)
{
fprintf(stderr,"pthread_mutex_unlock() error:%s\n",strerror(ret));
}
sleep(rand() % 3);
}
pthread_join(tid, NULL);
ret=pthread_mutex_destroy(&mutex);//销毁锁
if(ret!=0)
{
fprintf(stderr,"pthread_mutex_destroy() error:%s\n",strerror(ret));
}
return 0;
}
读写锁
特别强调,读写锁只有一把,但具备两种状态:
1读模式下加锁状态(读锁)
2.写模式下加锁状态(写锁)
特征:
1.读写锁是“写模式加锁”成功时,其它线程加锁都会被阻塞
2.读写锁“读模式加锁”成功时,其他线程以写模式加锁会阻塞
3.读锁、写锁并行阻塞,写锁优先级高。读锁也叫共享
#include
#include
#include
int counter=0;
//用pthread_rwlock_t类型,定义读写锁变量rwlock
pthread_rwlock_t rwlock;
/* 3个线程不定时写同一全局资源,5个线程不定时读同一全局资源*/
void *th_write(void *arg)
{
int t;
int i = (long int)arg;
while (1)
{
pthread_rwlock_wrlock(&rwlock);//以写模式加锁
t = counter;
counter++;
// sleep(1);
printf("=====write i=%d:tid=%lu:counter=%d ++counter=%d\n", i, pthread_self(), t, counter);
pthread_rwlock_unlock(&rwlock);
sleep(1);
}
return NULL;
}
void *th_read(void *arg)
{
int i = (long int)arg;
while (1)
{
pthread_rwlock_rdlock(&rwlock);//读线程间,读锁共享
printf("----------------------read i=%d:tid=%lu:counter=%d\n", i, pthread_self(), counter);
pthread_rwlock_unlock(&rwlock);
usleep(100000);
}
return NULL;
}
int main(void)
{
long int i;
pthread_t tid[8];
pthread_rwlock_init(&rwlock, NULL);
for(i=0;i<3;i++)
{
pthread_create(&tid[i], NULL, th_write, (void *)i);
}
for(i=0;i<5;i++)
{
pthread_create(&tid[i+3], NULL, th_read, (void *)i);
}
for(i=0;i<8;i++)
{
pthread_join(tid[i], NULL);
}
pthread_rwlock_destroy(&rwlock);
return 0;
}