互斥锁
如果信号量的值最多为
1
,那实际上相当于一个共享资源在任意时刻最多只能有一个线
程在访问,这样的逻辑被称为“互斥”。这时,有一种更加方便和语义更加准确的工具来满
足这种逻辑,他就是互斥锁。
“锁”是一种非常形象的说法:就像一个房间只能住一个人一样,任何人进去之后就把
门锁上了,其他任何人都不能进去,直到进去的那个人重新开开锁,即释放了这个锁资源为
止。
对互斥锁的操作无非就是:初始化、加锁、解锁、销毁。下面的代码通过展示两条线程
如何使用互斥锁来互斥地访问标准输出。
#include<stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
char *mem_map=NULL;
pthread_mutex_t lock;
void *function(void *arg)
{
char *msg=(char *)arg;
printf("线程号:%ld 收到参数:%s\n",pthread_self(),msg);
while (1)
{
printf("\nfunction等待锁 \n");
pthread_mutex_lock(&lock);
printf("function获取资源 已上锁\n ");
printf("msg:%s\n",mem_map);
sleep(1);
pthread_mutex_unlock(&lock);
}
}
int main(int argc, char const *argv[])
{
pthread_mutex_init(&lock,NULL);
mem_map=calloc(1,32);
pthread_t thread;
pthread_create(&thread, NULL,function, "Hello Gz123");
while (1)
{
printf("main 等待资源....\n ");
pthread_mutex_lock(&lock);
printf("main获取资源 以上锁 \n");
printf("main获取成功发送数据:");
fgets(mem_map,32,stdin);
sleep(1);
printf("main 释放资源\n");
pthread_mutex_unlock(&lock);
}
pthread_join(thread,NULL);
return 0;
}
读写锁
互斥锁的低效率,是因为没有更加细致地区分如何访问共享资源,一刀切地在任何时候
都只允许一条线程访问共享资源,而事实情况是读操作可以同时进行,只有写操作才需要互
斥,因此如果能根据访问的目的——读或者写,来分别加读锁(可以重复加)或者写锁(只
允许一次一个),就能就能极大地提高效率(尤其是存在大量读操作的情况下)。
读写锁的操作几乎跟互斥锁一样,唯一的区别的是在加锁的时候可以选择加读或者写
锁,下面的代码展示了如何使用它:
#include<stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
//定义线程间共享资源
//定义一个指针作用与线程之间的共享内存
char *mem_map=NULL;
pthread_rwlock_t rwlock;
void *function(void *arg)
{
char *msg=(char *)arg;
while (1)
{
pthread_rwlock_rdlock(&rwlock);
printf("线程%s号:%s \n",msg,mem_map);
pthread_rwlock_unlock(&rwlock);
sleep(2);
}
}
int main(int argc, char const *argv[])
{
pthread_rwlock_init(&rwlock,NULL);
mem_map=calloc(1,32);
pthread_t thread1;
pthread_t thread2;
pthread_t thread3;
pthread_t thread4;
pthread_create(&thread1, NULL,function, "1");
pthread_create(&thread2, NULL,function, "2");
pthread_create(&thread3, NULL,function, "3");
pthread_create(&thread4, NULL,function, "4");
while (1)
{
printf("main 等待上写锁....\n ");
pthread_rwlock_wrlock(&rwlock);
printf("main获取资源成功上写锁 \n");
fgets(mem_map,128,stdin);
pthread_rwlock_unlock(&rwlock);
printf("解除写锁....\n");
sleep(5);
}
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
pthread_join(thread3,NULL);
pthread_join(thread4,NULL);
return 0;
}