面试题答案
一键面试可能出现的竞态条件和同步问题
- 定时器创建冲突:多个线程同时调用
timer_create()
创建定时器时,可能导致资源分配冲突。 - 定时器操作冲突:例如一个线程在取消定时器时,另一个线程可能正在启动或修改该定时器,导致数据不一致。
解决方案
- 互斥锁(Mutex):用于保护共享资源,确保同一时间只有一个线程可以访问。
- 条件变量(Condition Variable):用于线程间的同步,使线程在特定条件满足时才进行操作。
代码示例
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>
#include <sys/timerfd.h>
pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t timer_cond = PTHREAD_COND_INITIALIZER;
timer_t global_timer;
int timer_cancel_requested = 0;
void* timer_operation(void* arg) {
struct itimerspec new_value;
new_value.it_value.tv_sec = 2;
new_value.it_value.tv_nsec = 0;
new_value.it_interval.tv_sec = 2;
new_value.it_interval.tv_nsec = 0;
pthread_mutex_lock(&timer_mutex);
if (timer_cancel_requested) {
pthread_mutex_unlock(&timer_mutex);
pthread_exit(NULL);
}
if (timer_create(CLOCK_REALTIME, NULL, &global_timer) == -1) {
perror("timer_create");
pthread_mutex_unlock(&timer_mutex);
pthread_exit(NULL);
}
if (timer_settime(global_timer, 0, &new_value, NULL) == -1) {
perror("timer_settime");
pthread_mutex_unlock(&timer_mutex);
pthread_exit(NULL);
}
pthread_mutex_unlock(&timer_mutex);
// 模拟其他定时器相关操作
sleep(5);
pthread_mutex_lock(&timer_mutex);
if (timer_delete(global_timer) == -1) {
perror("timer_delete");
}
pthread_mutex_unlock(&timer_mutex);
pthread_exit(NULL);
}
void* cancel_timer(void* arg) {
sleep(3);
pthread_mutex_lock(&timer_mutex);
timer_cancel_requested = 1;
pthread_cond_signal(&timer_cond);
pthread_mutex_unlock(&timer_mutex);
pthread_exit(NULL);
}
int main() {
pthread_t thread1, thread2;
if (pthread_create(&thread1, NULL, timer_operation, NULL) != 0) {
perror("pthread_create");
return 1;
}
if (pthread_create(&thread2, NULL, cancel_timer, NULL) != 0) {
perror("pthread_create");
return 1;
}
if (pthread_join(thread1, NULL) != 0) {
perror("pthread_join");
return 1;
}
if (pthread_join(thread2, NULL) != 0) {
perror("pthread_join");
return 1;
}
pthread_mutex_destroy(&timer_mutex);
pthread_cond_destroy(&timer_cond);
return 0;
}
在上述代码中:
- 互斥锁
timer_mutex
:保护global_timer
和timer_cancel_requested
等共享资源,确保在对其进行操作时不会发生竞态条件。 - 条件变量
timer_cond
:在cancel_timer
线程设置取消标志后,通过pthread_cond_signal
通知timer_operation
线程,使其在合适的时机检查并处理取消请求。这样可以确保在一个线程取消定时器时,不会影响其他线程对定时器的正常操作。