pthread 自旋锁使用
- 自旋锁:一种基于忙等待的锁,它不会使线程进入睡眠状态,即无上下文切换,而是循环尝试获取锁,直到成功为止。
pthread_spin_init
-
函数原型:
int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
- lock:指向要初始化的自旋锁对象的指针。
- pshared:指定了锁的共享属性,可以取以下两个值:
- PTHREAD_PROCESS_PRIVATE:锁只能由同一进程的线程使用,不支持跨进程共享。
- PTHREAD_PROCESS_SHARED:锁可以被多个进程中的线程共享。
- 返回值:成功返回 0,失败返回错误代码。
-
用于初始化自旋锁。
-
使用自旋锁时,应该先初始化再使用,最后再销毁。
pthread_spin_destroy
-
函数原型:
int pthread_spin_destroy(pthread_spinlock_t *lock);
- lock:指向要销毁的自旋锁对象的指针。
- 返回值:成功返回 0,失败返回错误代码。
-
用于销毁自旋锁。
-
销毁自旋锁之前,要确保没有任何线程正在持有该自旋锁,否则会导致未定义的结果。
pthread_spin_lock
-
函数原型:
int pthread_spin_lock(pthread_spinlock_t *lock);
- lock:指向要获取的自旋锁对象的指针。
- 返回值:成功返回 0,失败返回错误代码。
-
用于获取自旋锁。如果锁不可用,则以忙等待的方式阻塞当前线程,直到自旋锁可用。
pthread_spin_unlock
-
函数原型:
int pthread_spin_unlock(pthread_spinlock_t *lock);
- lock :指向要释放的自旋锁对象的指针。
- 返回值:成功返回 0,失败返回错误代码。
-
用于释放自旋锁。
-
如果当前线程没有持有该锁,则该函数的行为是未定义的。
示例
-
以下示例演示了两个线程交替写一个文件:
#include <stdio.h> #include <string.h> #include <pthread.h> pthread_spinlock_t g_spinlock; void* thread1_func(void* arg) { FILE* fp = (FILE*)arg; // 获取自旋锁 pthread_spin_lock(&g_spinlock); // 进入临界区,访问共享资源 char* s = "thread1: hello\n"; fwrite(s, strlen(s), 1, fp); // 释放自旋锁 pthread_spin_unlock(&g_spinlock); return NULL; } void* thread2_func(void* arg) { FILE* fp = (FILE*)arg; // 获取自旋锁 pthread_spin_lock(&g_spinlock); // 进入临界区,访问共享资源 char* s = "thread2: hello\n"; fwrite(s, strlen(s), 1, fp); // 释放自旋锁 pthread_spin_unlock(&g_spinlock); return NULL; } int main() { // 新建文件 FILE* fp = fopen("test.txt", "wt"); // 初始化自旋锁 pthread_spin_init(&g_spinlock, PTHREAD_PROCESS_PRIVATE); // 创建线程 pthread_t th1; pthread_t th2; pthread_create(&th1, NULL, thread1_func, fp); pthread_create(&th2, NULL, thread2_func, fp); // 等待线程结束 pthread_join(th1, NULL); pthread_join(th2, NULL); // 销毁自旋锁 pthread_spin_destroy(&g_spinlock); // 关闭文件 fclose(fp); return 0; }