多个线程同时访问共享资源,最终结果依赖于线程的执行顺序。
两个或多个线程同时访问同一个变量,且至少有一个线程在写入,而没有同步机制。
示例:无同步的计数器
#include <stdio.h>
#include <pthread.h>
int counter = 0;
void* increment(void* arg) {
for (int i = 0; i < 1000000; i++) {
counter++; // 非原子操作:读-改-写
}
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_create(&t1, NULL, increment, NULL);
pthread_create(&t2, NULL, increment, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Expected: 2000000, Actual: %d\n", counter);
return 0;
}
问题:输出不确定,可能小于2000000。
#include <pthread.h>
// 动态初始化
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
// 静态初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// 销毁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
注意事项:
// 阻塞加锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
// 非阻塞加锁
int pthread_mutex_trylock(pthread_mutex_t *mutex);
// 解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
返回值:
void* worker(void* arg) {
pthread_mutex_t* mutex = (pthread_mutex_t*)arg;
if (pthread_mutex_trylock(mutex) == 0) {
// 成功获得锁
printf("Thread %lu got the lock\n", pthread_self());
// 临界区操作
pthread_mutex_unlock(mutex);
} else {
// 无法获得锁,执行其他任务
printf("Thread %lu couldn't get lock\n", pthread_self());
}
return NULL;
}
pthread_mutex_timedlock// 线程1
pthread_mutex_lock(&lockA);
pthread_mutex_lock(&lockB); // 可能死锁
// 线程2
pthread_mutex_lock(&lockB);
pthread_mutex_lock(&lockA); // 可能死锁
解决方案:统一锁顺序
// 所有线程都按此顺序
pthread_mutex_lock(&lockA);
pthread_mutex_lock(&lockB);
pthread_mutex_t mutex;
void signal_handler(int signum) {
pthread_mutex_lock(&mutex); // 危险!
// 处理信号
pthread_mutex_unlock(&mutex);
}
void* worker(void* arg) {
pthread_mutex_lock(&mutex);
// 长时间操作
pthread_mutex_unlock(&mutex);
return NULL;
}
问题:如果信号在临界区中发生,会导致死锁。
解决方案:
sigaction 的 SA_RESTART 选项trylock)#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define BUFFER_SIZE 10
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int buffer = 0;
int count = 0; // 缓冲区中的物品数量
void* producer(void* arg) {
for (int i = 0; i < 20; i++) {
pthread_mutex_lock(&mutex);
if (count < BUFFER_SIZE) {
buffer++;
count++;
printf("Producer: produced item %d, total: %d\n", i, count);
} else {
printf("Producer: buffer full, waiting...\n");
}
pthread_mutex_unlock(&mutex);
usleep(100000); // 100ms
}
return NULL;
}
void* consumer(void* arg) {
for (int i = 0; i < 20; i++) {
pthread_mutex_lock(&mutex);
if (count > 0) {
buffer--;
count--;
printf("Consumer: consumed item %d, total: %d\n", i, count);
} else {
printf("Consumer: buffer empty, waiting...\n");
}
pthread_mutex_unlock(&mutex);
usleep(150000); // 150ms
}
return NULL;
}
int main() {
pthread_t prod_thread, cons_thread;
pthread_create(&prod_thread, NULL, producer, NULL);
pthread_create(&cons_thread, NULL, consumer, NULL);
pthread_join(prod_thread, NULL);
pthread_join(cons_thread, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
编译命令:
gcc -o simple_pc simple_pc.c -pthread
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct {
int count;
pthread_mutex_t mutex;
} ThreadSafeCounter;
void counter_init(ThreadSafeCounter* counter, int initial) {
counter->count = initial;
pthread_mutex_init(&counter->mutex, NULL);
}
void counter_destroy(ThreadSafeCounter* counter) {
pthread_mutex_destroy(&counter->mutex);
}
void counter_increment(ThreadSafeCounter* counter) {
pthread_mutex_lock(&counter->mutex);
counter->count++;
pthread_mutex_unlock(&counter->mutex);
}
void counter_decrement(ThreadSafeCounter* counter) {
pthread_mutex_lock(&counter->mutex);
counter->count--;
pthread_mutex_unlock(&counter->mutex);
}
int counter_get(ThreadSafeCounter* counter) {
pthread_mutex_lock(&counter->mutex);
int value = counter->count;
pthread_mutex_unlock(&counter->mutex);
return value;
}
void* increment_worker(void* arg) {
ThreadSafeCounter* counter = (ThreadSafeCounter*)arg;
for (int i = 0; i < 1000000; i++) {
counter_increment(counter);
}
return NULL;
}
int main() {
ThreadSafeCounter counter;
counter_init(&counter, 0);
pthread_t t1, t2;
pthread_create(&t1, NULL, increment_worker, &counter);
pthread_create(&t2, NULL, increment_worker, &counter);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Expected: 2000000, Actual: %d\n", counter_get(&counter));
counter_destroy(&counter);
return 0;
}
编译命令:
gcc -o thread_safe_counter thread_safe_counter.c -pthread
A:
A:
pthread_mutex_trylock 的使用场景?A:
A:
PTHREAD_MUTEX_NORMAL:普通互斥锁PTHREAD_MUTEX_ERRORCHECK:错误检查锁PTHREAD_MUTEX_RECURSIVE:递归锁PTHREAD_MUTEX_DEFAULT:默认类型A: