多线程并发锁分类以及简单实例

多线程并发锁

包括自旋锁、互斥锁、无锁

POSIX接口

posix接口提供linux下线程操作库,posix默认生成的线程占用8M空间

  1. pthread_create线程创建函数

    pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(* func)(void *), void *arg) // func是函数指针,是线程要调用的函数,arg是给调用函数传的参数
    

互斥锁mutex

线程试图访问被锁资源时,线程会被阻塞。锁释放的时候,会唤醒所有该锁上阻塞的线程。适用于锁的内容较多的情况,比如队列

pthread_mutex_t mutex; // 声明互斥量
pthread_mutex_init(&mutex, NULL); // 默认初始化
ptherad_mutex_lock(&mutex); // 加锁
ptherad_mutex_lock(&mutex); // 解锁

自旋锁spinlock

自旋锁会一直去尝试获取锁,相当于一个while循环获取。适用于锁的内容很少比如变量,使用自选锁,等待代价小于线程切换。此时cpu会发生空转。

pthread_spinlock_t spinlock; // 声明自旋锁
pthread_spin_init(&spinlock, PTHERAD_PROCESS_PRIVATE); // 默认初始化
ptherad_spin_lock(&spinlock); // 加锁
ptherad_spin_lock(&spinlock); // 解锁

原子操作-无锁

原子操作解决对应变量需要加锁的问题,原子操作能够将变量的指令变为单条CPU指令,这样就能够解决线程之间不同步的问题。原子操作的速度更快。

int inc(int* value, int add){
    int old;
    // volatile指示编译器不要对变量进行优化
    __asm__ volatile(
        "lock; xaddl %2, %1"
        : "=a" (old)
        : "m" (*value), "a" (add)
        : "cc", "memory"
    );
}

CAS

cas指的是Compare-And-Swap原子操作,能够保证并发线程对共享数据安全访问和修改。

实现思路

compare用于检测内存地址当前值是否与期望值相等,swap如果期望值等于当前值,则将当前值作为新值。

实现方式

void cas(int *ptr, int expected, int desired) {
    __asm__ volatile (
        "lock; cmpxchg %2, %0\n" // 使用LOCK前缀的cmpxchg指令
        : "+m" (*ptr), "+a" (expected) // 操作数约束
        : "r" (desired) // 操作数约束
        : "memory" // 标记内存操作
    );
}
posted @ 2024-07-21 09:02  云中锦书来  阅读(1)  评论(0编辑  收藏  举报