自旋锁(Spinlock)是一种特殊的锁机制,当线程尝试获取锁失败时,不会立即进入睡眠状态,而是会忙等待(即“自旋”),不断检查锁是否可用。自旋锁适合于锁被持有的时间非常短的场景,这样可以避免线程上下文切换的开销。
在Linux内核中,自旋锁的实现主要依赖于spinlock_t
类型和相关函数。以下是一个简单的自旋锁实现示例:
#include <linux/spinlock.h>
// 定义一个自旋锁
spinlock_t my_spinlock;
// 初始化自旋锁
void init_spinlock(void) {
spin_lock_init(&my_spinlock);
}
// 获取自旋锁
void critical_section(void) {
unsigned long flags;
spin_lock_irqsave(&my_spinlock, flags); // 获取自旋锁并保存中断状态
// 临界区代码
// ...
spin_unlock_irqrestore(&my_spinlock, flags); // 释放自旋锁并恢复中断状态
}
以下是一个简单的自旋锁实现示例:
#include <stdio.h>
#include <pthread.h>
#include <stdatomic.h>
// 定义一个自旋锁
atomic_flag lock = ATOMIC_FLAG_INIT;
// 临界区代码
void critical_section(int *counter) {
while (atomic_flag_test_and_set_explicit(&lock, memory_order_acquire)); // 获取自旋锁
(*counter)++;
atomic_flag_clear_explicit(&lock, memory_order_release); // 释放自旋锁
}
// 线程函数
void* thread_func(void* arg) {
int *counter = (int*)arg;
for (int i = 0; i < 100000; i++) {
critical_section(counter);
}
return NULL;
}
int main() {
int counter = 0;
pthread_t threads[10];
// 创建多个线程
for (int i = 0; i < 10; i++) {
pthread_create(&threads[i], NULL, thread_func, &counter);
}
// 等待线程结束
for (int i = 0; i < 10; i++) {
pthread_join(threads[i], NULL);
}
printf("Counter: %d
", counter);
return 0;
}
在这个示例中,我们使用atomic_flag
来实现一个简单的自旋锁,并在多个线程中使用它来保护一个共享的计数器。
领取专属 10元无门槛券
手把手带您无忧上云