3yx这个网站做刷单,汕头优化网站,地产公司网站建设,建筑工程施工承包合同1、概念
1.1 定义
自旋锁#xff08;Spinlock#xff09;是一种特殊的锁机制#xff0c;当线程尝试获取锁而锁不可用时#xff0c;线程会进入忙等待#xff08;即循环检查锁是否可用#xff09;#xff0c;而不是进入睡眠状态。这种机制适用于锁持有时间非常短的场景Spinlock是一种特殊的锁机制当线程尝试获取锁而锁不可用时线程会进入忙等待即循环检查锁是否可用而不是进入睡眠状态。这种机制适用于锁持有时间非常短的场景因为它避免了线程上下文切换的开销。然而如果锁持有时间较长自旋锁可能会导致CPU资源的浪费。
1.2 特点
忙等待自旋锁会在获取锁时不断循环检查锁的状态直到获取到锁为止。这种忙等待的方式可以减少线程切换的开销适用于对锁的占用时间较短的情况。无阻塞自旋锁不会将线程阻塞因此适用于对锁的占用时间较短、竞争不激烈的情况。适用于多核CPU自旋锁在多核CPU上效果更好因为在一个核上的线程忙等待时其他核上的线程可以继续执行。
1.3 应用场景
短期占用适用于对锁的占用时间较短的情况避免线程切换的开销。低竞争适用于竞争不激烈的情况避免线程频繁地阻塞和唤醒。多核CPU在多核CPU上自旋锁的效率更高因为可以充分利用多核并行执行的优势
2、常用接口
2.1 pthread_spin_init
初始化一个自旋锁。
pthread_spin_init(pthread_spinlock_t *lock, int pshared)
入参 lock指向要初始化的自旋锁的指针。pshared指定锁的共享属性通常设置为PTHREAD_PROCESS_PRIVATE。返回值若成功返回0否则返回错误码。
2.2 pthread_spin_lock
获取自旋锁。
pthread_spin_lock(pthread_spinlock_t *lock)
入参 lock指向要获取的自旋锁的指针。返回值若成功返回0否则返回错误码。
2.3 pthread_spin_trylock
尝试获取自旋锁如果锁已被其他线程占用则立即返回。
pthread_spin_trylock(pthread_spinlock_t *lock)
入参 lock指向要尝试获取的自旋锁的指针。返回值若成功获取锁返回0若锁已被占用返回EBUSY其他情况返回错误码。
2.4 pthread_spin_unlock
释放自旋锁。
pthread_spin_unlock(pthread_spinlock_t *lock)
作用释放自旋锁。入参 lock指向要释放的自旋锁的指针。返回值若成功返回0否则返回错误码。
2.5 pthread_spin_destroy
销毁一个已经初始化的自旋锁。
pthread_spin_destroy(pthread_spinlock_t *lock)
作用销毁一个已经初始化的自旋锁。入参 lock指向要销毁的自旋锁的指针。返回值若成功返回0否则返回错误码。
3、编程测试
分别测试使用自旋锁和不使用自旋锁操作全局变量的情况。定义一个全局共享变量shared_resource和两个线程都将访问并修改它。使用pthread_spinlock_t类型的变量spinlock作为自旋锁。在thread_function函数中线程首先尝试使用pthread_spin_lock函数获取自旋锁如果锁不可用线程会忙等待直到锁可用。获取锁后线程访问并修改共享资源然后释放锁使用pthread_spin_unlock函数。最后主线程等待两个工作线程完成并输出最终的共享资源值。
先将自旋锁代码注释掉测试程序
#include stdio.h
#include stdlib.h
#include pthread.h // 全局共享变量
int shared_resource 0; // 自旋锁
pthread_spinlock_t spinlock; // 线程函数
void* thread_function(void* arg)
{ int thread_id *(int*)arg; // 尝试获取自旋锁 // pthread_spin_lock(spinlock); // 访问共享资源 for (int i 0; i 100000; i) { shared_resource 1; } printf(Thread %d finished, shared_resource %d\n, thread_id, shared_resource); // 释放自旋锁 // pthread_spin_unlock(spinlock); return NULL;
} int main()
{ // 初始化自旋锁 if (pthread_spin_init(spinlock, 0) ! 0) { printf(Spinlock initialization failed\n); return 1; } // 创建两个线程 pthread_t thread1, thread2; int thread1_id 1, thread2_id 2; if (pthread_create(thread1, NULL, thread_function, thread1_id) ! 0) { printf(Thread 1 creation failed\n); return 1; } if (pthread_create(thread2, NULL, thread_function, thread2_id) ! 0) { printf(Thread 2 creation failed\n); return 1; } // 等待线程结束 pthread_join(thread1, NULL); pthread_join(thread2, NULL); // 销毁自旋锁 pthread_spin_destroy(spinlock); printf(Final shared_resource value: %d\n, shared_resource); return 0;
}测试结果异常结果不可控 去掉注释测试自旋锁功能
#include stdio.h
#include stdlib.h
#include pthread.h // 全局共享变量
int shared_resource 0; // 自旋锁
pthread_spinlock_t spinlock; // 线程函数
void* thread_function(void* arg)
{ int thread_id *(int*)arg; // 尝试获取自旋锁 pthread_spin_lock(spinlock); // 访问共享资源 for (int i 0; i 100000; i) { shared_resource 1; } printf(Thread %d finished, shared_resource %d\n, thread_id, shared_resource); // 释放自旋锁 pthread_spin_unlock(spinlock); return NULL;
} int main()
{ // 初始化自旋锁 if (pthread_spin_init(spinlock, 0) ! 0) { printf(Spinlock initialization failed\n); return 1; } // 创建两个线程 pthread_t thread1, thread2; int thread1_id 1, thread2_id 2; if (pthread_create(thread1, NULL, thread_function, thread1_id) ! 0) { printf(Thread 1 creation failed\n); return 1; } if (pthread_create(thread2, NULL, thread_function, thread2_id) ! 0) { printf(Thread 2 creation failed\n); return 1; } // 等待线程结束 pthread_join(thread1, NULL); pthread_join(thread2, NULL); // 销毁自旋锁 pthread_spin_destroy(spinlock); printf(Final shared_resource value: %d\n, shared_resource); return 0;
}测试结果正常 4、总结
本文讲解了Linux线程同步中使用的自旋锁的定义和应用场景列举了编程中常用的接口并编写测试用例进行测试。