- 设计思路:
- 信号处理函数的选择:选择可重入的函数在信号处理函数中调用。避免使用不可重入的函数,如标准I/O函数(
printf
等),因为它们可能使用内部静态数据结构,在多线程环境下调用会导致数据竞争和不一致。
- 共享资源访问控制:确保信号处理函数对共享资源的访问不会干扰其他线程对共享资源的正常操作。
- 线程安全的数据结构:如果可能,尽量使用线程安全的数据结构来存储共享资源,这样可以减少同步机制的复杂度。
- 可能用到的同步机制:
- 互斥锁(Mutex):
- 在访问共享资源前,使用
pthread_mutex_lock
函数获取互斥锁。在信号处理函数和其他线程访问共享资源前都要获取这个互斥锁。
- 例如:
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
pthread_mutex_t mutex;
int shared_variable;
void signal_handler(int signum) {
pthread_mutex_lock(&mutex);
// 处理共享资源,例如修改shared_variable
shared_variable++;
pthread_mutex_unlock(&mutex);
}
void* thread_function(void* arg) {
pthread_mutex_lock(&mutex);
// 线程中访问共享资源
printf("Thread accessing shared variable: %d\n", shared_variable);
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_t thread;
pthread_mutex_init(&mutex, NULL);
shared_variable = 0;
signal(SIGUSR1, signal_handler);
pthread_create(&thread, NULL, thread_function, NULL);
pthread_join(thread, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
- 信号量(Semaphore):
- 可以使用信号量来控制对共享资源的访问。例如,初始化一个值为1的二元信号量,在访问共享资源前使用
sem_wait
获取信号量,访问结束后使用sem_post
释放信号量。
- 读写锁(Read - Write Lock):
- 如果共享资源的访问模式主要是读多写少,可以使用读写锁。信号处理函数如果是写操作,获取写锁(
pthread_rwlock_wrlock
),其他线程读操作获取读锁(pthread_rwlock_rdlock
)。这样可以允许多个线程同时读共享资源,但写操作时会独占资源,避免数据冲突。