Linux实现线程同步的方式有很多,主要包括以下几种:
1、互斥锁(Mutex):互斥锁是一种用于保护共享资源的同步原语,当一个线程获得互斥锁时,其他线程必须等待该锁被释放才能继续执行,这可以确保在同一时刻只有一个线程访问共享资源,在Linux中,可以使用pthread_mutex_t
结构体和相关的函数来实现互斥锁。
2、读写锁(Read-Write Lock):读写锁允许多个线程同时读取共享资源,但只允许一个线程写入,这可以提高性能,因为读取操作通常比写入操作更频繁,在Linux中,可以使用pthread_rwlock_t
结构体和相关的函数来实现读写锁。
3、条件变量(Condition Variables):条件变量是一种用于线程间通信的同步原语,当一个线程需要等待某个条件满足时,它可以等待在一个条件变量上,另一个线程可以在条件满足时通知等待的线程,在Linux中,可以使用pthread_cond_t
结构体和相关的函数来实现条件变量。
4、信号量(Semaphore):信号量是一种计数器,用于管理对共享资源的访问,它允许多个线程限制同时访问共享资源的数量,在Linux中,可以使用sem_t
结构体和相关的函数来实现信号量。
5、忙等待(Busy Wait)和自旋锁(Spin Lock):忙等待是一种无限循环,直到条件满足为止,这种方法简单且易于实现,但可能导致CPU资源浪费,自旋锁是一种特殊的忙等待,当一个线程尝试获取一个已经被锁定的锁时,它会不断检查该锁是否可用,而不是进入忙等待状态,在Linux中,可以使用原子操作和硬件指令来实现自旋锁。
6、事件(Event):事件是一种同步原语,用于在线程之间传递信号,一个线程可以等待一个事件发生,而另一个线程可以在适当的时候设置该事件,在Linux中,可以使用eventfd
系统调用和相关的函数来实现事件。
下面是一个使用互斥锁实现生产者消费者问题的示例:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; int in = 0; int out = 0; int count = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER; pthread_cond_t not_full = PTHREAD_COND_INITIALIZER; void *producer(void *arg) { int item; while (1) { item = rand() % 100; pthread_mutex_lock(&mutex); while (count == BUFFER_SIZE) { pthread_cond_wait(¬_full, &mutex); } buffer[in] = item; in = (in + 1) % BUFFER_SIZE; count++; printf("Producer produced %d at buffer position %d. Total items: %d ", item, in, count); pthread_cond_signal(¬_empty); pthread_mutex_unlock(&mutex); sleep(rand() % 3); } } void *consumer(void *arg) { int item; while (1) { pthread_mutex_lock(&mutex); while (count == 0) { pthread_cond_wait(¬_empty, &mutex); } item = buffer[out]; out = (out + 1) % BUFFER_SIZE; count--; printf("Consumer consumed %d from buffer position %d. Total items: %d ", item, out, count); pthread_cond_signal(¬_full); pthread_mutex_unlock(&mutex); sleep(rand() % 3); } } int main() { pthread_t producer_thread, consumer_thread; pthread_create(&producer_thread, NULL, producer, NULL); pthread_create(&consumer_thread, NULL, consumer, NULL); pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); pthread_mutex_destroy(&mutex); pthread_cond_destroy(¬_empty); pthread_cond_destroy(¬_full); return 0; }
在这个示例中,我们使用了互斥锁来保护共享缓冲区buffer
,以及两个条件变量not_empty
和not_full
来控制生产者和消费者之间的同步,生产者线程在向缓冲区添加元素时需要获取互斥锁,而消费者线程在从缓冲区取出元素时需要获取互斥锁,这样可以确保在同一时刻只有一个线程访问缓冲区,从而避免了数据竞争和不一致的问题。
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/118451.html