多线程操作与安全

1 互斥锁

1.1 使用场景

互斥锁的特性:
当遇到锁被占用,会进行cpu切换,等锁可以用后再切换回来。
使用场景:
操作复杂耗时或者存在有系统调用,采用互斥锁。

1.2 基本操作

锁的使用很简单,就三个api,初始化,加锁,解锁。需要注意锁的粒度,一般是需要根据临界资源大小来定。有时候也会因为降低代码复杂度,增加锁的粒度。

#include <pthread.h>
pthread_mutex_t mutex;
//1. 初始化
pthread_mutex_init(&mutex, NULL);
//2. 加锁
pthread_mutex_lock(&mutex);
//3. 解锁
pthread_mutex_unlock(&mutex);
//4. 释放
pthread_mutex_destroy(&mutex);

2 自旋锁

2.1 使用场景

自旋锁的特性:
当遇到锁被占用,不会让出cpu,空转等待。
使用场景:
临界资源操作简单时间短,没有系统调用,采用自旋锁。

2.2 基本操作

初始化带一个选项参数,一般采用PTHREAD_PROCESS_SHARED,允许多线程操作自旋锁。其他操作与互斥锁一致,就是使用场景上的差别。

#include <pthread.h>
pthread_spinlock_t spinlock;
//1. 初始化
//PTHREAD_PROCESS_SHARED:允许任何有权访问分配自旋锁的内存的线程操作自旋锁
pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED);
//2. 加锁
pthread_spin_lock(&spinlock);
//3. 解锁
pthread_spin_unlock(&spinlock);
//4. 释放
pthread_spin_destroy(&spinlock);

3 原子操作

3.1 使用场景

原子操作的特性:
原子操作是也是解决线程安全的一种操作,将复杂的操作变成一条cpu指令。
使用场景:
原子操作主要是指令集的操作,需要cpu的指令集支持才

3.2 基本操作

这里实现两个比较常用的原子操作一个是自增或者自减运算,利用的是汇编指令支持;另一个是比较火的指令CAS(compare and swap)操作,它也是需要cpu指令集支持,具体功能是比较并且替换。

//自增原子操作
int inc(int *value, int add) {

	int old;
	__asm__ volatile (
		"lock; xaddl %2, %1;"
		: "=a" (old)
		: "m" (*value), "a" (add)
		: "cc", "memory"
	);
	return old;

}
//CAS原子操作(比较a==b,a=c)
cmpxchg(a, b, c);
//相当于
if(a == b)
{
	a = c;
}

4 线程私有空间

4.1 使用场景

线程私有空间的特性:

预先为线程开辟私有空间,线程内部共享。
使用场景:
线程私有空间为了解决线程内部的资源的共享,类似线程内部的全局变量。

4.2 基本操作

私有空间操作也比较简单,创建私有空间;设置私有空间值,支持结构体,字符串,数字等等;获取私有空间数据主要是利用get函数和强转即可。支持跨函数传递,只要在线程内即可。

#include <pthread.h>
pthread_key_t key;
//1. 私有空间创建
pthread_key_create(&key, NULL);
//2. 设置数据到私有空间
pthread_setspecific(key, ptr);
//3. 获取数据
ptr = pthread_getspecific(key);
//4. 释放
pthread_key_delete(key);

5 信号量

5.1 使用场景

信号量的特性:

阻塞等待条件触发后才执行;
使用场景:
一般用于生产消费模型,生产者负责发送通知,消费者当生产队列为空则阻塞等待。

5.2 基本操作

信号量操作,包括初始化;信号通知;信号等待;广播通知和释放操作;需要注意的是等待信号需要与锁配合使用。broadcast是唤醒所有被阻塞的线程,一般在cond释放的时候使用。

#include <pthread.h>
pthread_cond_t cond;
pthread_mutex_t mutex;
//1. 初始化
pthread_cond_init(&cond);
//3. 等待需要与互斥锁配合使用
pthread_mutex_lock(&pool->mtx);
	while (pool->cons == NULL) {
		if (pool->terminate) break;
		pthread_cond_wait(&pool->cond, &pool->mtx);
	}
pthread_mutex_unlock(&pool->mtx);
//3. 单一通知信号
pthread_cond_signal(&cond);
//4. 广播通知信号
pthread_cond_broadcast(&cond);
//5. 释放
pthread_cond_destroy(&cond);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值