Linux系统中,实现线程同步的方式大致分为六种,其中包括:互斥锁、自旋锁、信号量、条件变量、读写锁、屏障。最常用的线程同步方式就是互斥锁、自旋锁、信号量:
1、互斥锁
互斥锁本质就是一个特殊的全局变量,拥有lock和unlock两种状态,unlock的互斥锁可以由某个线程获得,当互斥锁由某个线程持有后,这个互斥锁会锁上变成lock状态,此后只有该线程有权力打开该锁,其他想要获得该互斥锁的线程都会阻塞,直到互斥锁被解锁。
互斥锁的类型:
①普通锁:互斥锁默认类型。当一个线程对一个普通锁加锁以后,其余请求该锁的线程将形成一个等待队列,并在锁解锁后按照优先级获得它,这种锁类型保证了资源分配的公平性。一个线程如果对一个已经加锁的普通锁再次加锁,将引发死锁对一个已经被其他线程加锁的普通锁解锁,或者对一个已经解锁的普通锁再次解锁,将导致不可预期的后果。
②检错锁:一个线程如果对一个已经加锁的检错锁再次加锁,则加锁操作返回EDEADLK对一个已经被其他线程加锁的检错锁解锁或者对一个已经解锁的检错锁再次解锁,则解锁操作返回EPERM。
③嵌套锁:该锁允许一个线程在释放锁之前多次对它加锁而不发生死锁其他线程要获得这个锁,则当前锁的拥有者必须执行多次解锁操作对一个已经被其他线程加锁的嵌套锁解锁,或者对一个已经解锁的嵌套锁再次解锁,则解锁操作返回EPERM。
④默认锁:一个线程如果对一个已经解锁的默认锁再次加锁,或者对一个已经被其他线程加锁的默认锁解锁,或者对一个解锁的默认锁解锁,将导致不可预期的后果这种锁实现的时候可能被映射成上述三种锁之一。
【老男孩教育】Linux运维云计算课程汇集了虚拟化、云计算、安全攻防、Python开发、SRE等技术,课堂效率高、内容丰富全面,由浅入深,循序渐进,帮助学员稳扎稳打,夯实基础,在有限的时间内帮助学员高效提升,成为符合企业需求的技术型人才。
2、自旋锁
自旋锁顾名思义就是一个死循环,不停的轮询,当一个线程未获得自旋锁时,不会像互斥锁一样进入阻塞休眠状态,而是不停的轮询获取锁,如果自旋锁能够很快被释放,那么性能就会很高,如果自旋锁长时间不能够被释放,甚至里面还有大量的IO阻塞,就会导致其他获取锁的线程一直空轮询,导致CPU使用率达到100%,特别CPU时间。
3、信号量
信号量是一个计数器,用于控制访问有限共享资源的线程数。
#include<stdio.h>#include<pthread.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<semaphore.h>
#include<stdlib.h>
#define N 3
pthread_mutex_t mutex_w,mutex_r// 定义读写互斥锁
sem_t sem_w,sem_r//定义读写信号量
int data[N]
int pos=0
void *function_w(void *arg)
{
int w = *(int *)arg
pos = w
while(1)
{
usleep(100000)
sem_wait(&sem_w)//等待可写的资源
pthread_mutex_lock(&mutex_w)//禁止别的线程写此资源
data[pos] = w
w++
w++
w++
pos++
pos=pos%N
pthread_mutex_unlock(&mutex_w)//别的线程可写此资源
sem_post(&sem_r)// 释放一个读资源
}
return (void *)0
}
void *function_r(void *arg)
{
while(1)
{
sem_wait(&sem_r)//等待可读的资源
pthread_mutex_lock(&mutex_r)//禁止别的线程读此资源
printf("%d\n",data[(pos+N-1)%N])
pthread_mutex_unlock(&mutex_r)//别的线程可读此资源
sem_post(&sem_w)// 释放一个写资源
}
return (void *)0
}
int main(int argc, char **argv)
{
pthread_t thread[2*N]
int i
pthread_mutex_init(&mutex_w,NULL)
pthread_mutex_init(&mutex_r,NULL)
sem_init(&sem_w,0,N)
sem_init(&sem_r,0,0)
for(i=0i<Ni++)
{
if ( pthread_create(&thread[i],NULL,function_w,(void *)&i) <0)//创建写线程
{
perror("pthread_create")
exit(-1)
}
}
for(i=Ni<2*Ni++)
{
if ( pthread_create(&thread[i],NULL,function_r,NULL) <0)//创建读线程
{
perror("pthread_create")
exit(-1)
}
}
sleep(1)
return(0)
}
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)