linux c 编程 ------ 线程间通信与同步机制

1、互斥锁
常用函数:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);//互斥初始化 int pthread_mutex_destroy(pthread_mutex_t *mutex);//销毁互斥 int pthread_mutex_lock(pthread_mutex_t *mutex);//锁定互斥 int pthread_mutex_unlock(pthread_mutex_t *mutex);//解锁互斥 int pthread_mutex_trylock(pthread_mutex_t *mutex);//非阻塞的锁定互斥锁
2、条件变量
pthread_cond_wait 自动解锁互斥量(如同执行了pthread_unlock_mutex),并等待条件变量触发。这时线程挂起,不占用CPU时间,直到条件变量被触发(变量为true)。在调用 pthread_cond_wait之前,应用程序必须加锁互斥量。pthread_cond_wait函数返回前,自动重新对互斥量加锁(如同执行了pthread_lock_mutex)。
使用案例:
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int data_ready = 0; void* producer(void* arg) { // 生成数据 pthread_mutex_lock(&mutex); data_ready = 1; pthread_cond_signal(&cond); // 通知消费者 pthread_mutex_unlock(&mutex); return NULL; } void* consumer(void* arg) { pthread_mutex_lock(&mutex); while (!data_ready) { pthread_cond_wait(&cond, &mutex); // 等待生产者通知 } // 消费数据 pthread_mutex_unlock(&mutex); return NULL; }
唤醒条件有两种形式,pthread_cond_signal()唤醒一个等待该条件的线程,存在多个等待线程时按入队顺序唤醒其中一个;而pthread_cond_broadcast()则唤醒所有等待线程
3、信号量
函数:
int sem_init (sem_t *sem , int pshared, unsigned int value); int sem_post(sem_t *sem); int sem_wait(sem_t *sem); int sem_destroy(sem_t *sem);
4、读写锁
1.如果一个线程用读锁锁定了临界区,那么其他线程也可以用读锁来进入临界区,这样就可以多个线程并行操作。但这个时候,如果再进行写锁加锁就会发生阻塞,写锁请求阻塞后,后面如果继续有读锁来请求,这些后来的读锁都会被阻塞!这样避免了读锁长期占用资源,防止写锁饥饿!
2.如果一个线程用写锁锁住了临界区,那么其他线程不管是读锁还是写锁都会发生阻塞!
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout); int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout); int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
5、内存屏障
POSIX线程库提供了pthread_barrier,这是一种专门用于线程同步的屏障机制。屏障允许一组线程在某个点上等待,直到所有线程都到达该点,然后所有线程才能继续执行。
使用场景
- 当多个线程需要并行执行某些任务,但在某个关键点上需要同步时(例如,并行计算中的迭代同步)。
- 确保所有线程在继续执行之前完成某些初始化或计算。
#include <pthread.h> #include <stdio.h> #define NUM_THREADS 4 pthread_barrier_t barrier; void* thread_func(void* arg) { int thread_id = *(int*)arg; printf("Thread %d: Doing some work...\n", thread_id); // 模拟工作 sleep(1); printf("Thread %d: Reached the barrier.\n", thread_id); pthread_barrier_wait(&barrier); // 等待所有线程到达屏障 printf("Thread %d: All threads have passed the barrier. Continuing...\n", thread_id); return NULL; } int main() { pthread_t threads[NUM_THREADS]; int thread_ids[NUM_THREADS]; // 初始化屏障 pthread_barrier_init(&barrier, NULL, NUM_THREADS + 1); // +1 是因为主线程可能也需要等待 for (int i = 0; i < NUM_THREADS; i++) { thread_ids[i] = i; pthread_create(&threads[i], NULL, thread_func, &thread_ids[i]); } // 主线程也可以等待屏障(可选) printf("Main thread: Waiting for threads...\n"); pthread_barrier_wait(&barrier); printf("Main thread: All threads have passed the barrier.\n"); for (int i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } // 销毁屏障 pthread_barrier_destroy(&barrier); return 0; }

浙公网安备 33010602011771号