24.6.4同步典型模式

在MySQL中有相当多的地方,我们使用了这样的同步模式:

pthread_mutex_lock(互斥);螺纹- > enter_cond (&condition_variable,互斥,new_message);if (!)thd->killed && !end_of_wait_condition) DEBUG_SYNC(thd, "sync_point_name");# endif虽然(!pthread_cond_wait(&condition_variable, &mutex);螺纹- > exit_cond (old_message);

这里的一些解释:

Thd ->enter_cond()用于注册条件变量和Thd ->mysys_var中的互斥锁。这样做是为了允许线程从睡眠中被中断(杀死)。另一个线程可以在这个线程的THD::mysys_var中找到要发送信号的条件变量和用于同步的互斥锁。

Thd ->enter_cond()要求提前获取互斥锁。

Thd ->exit_cond()注销条件变量和互斥锁,并释放互斥锁。

如果你想在等待中有一个调试同步点,请把它放在enter_cond()后面。只有这样,你才能安全地决定是否等待。当同步点发出信号时,THD::proc_info也会正确。DEBUG_SYNC设置自己的proc_info,但是在释放内部互斥锁之前恢复之前的proc_info。当另一个线程看到信号时,它也会在进入同步点之前看到proc_info。在本例中,它将是"new_message",它与要同步的等待相关联。

在上面的例子中,等待条件在同步点之前重复。这样做是为了跳过同步点,如果没有发生等待。同步点位于循环之前(而不是循环内部),只命中一次。在等待条件为真的情况下,条件变量可能被多次发出信号。

有点跑题:在某些地方,循环是围绕整个同步模式进行的:

而(!Thd ->杀死&& !end_of_wait_condition) {pthread_mutex_lock(&互斥锁);螺纹- > enter_cond (&condition_variable,互斥,new_message);如果(!pthread_cond_wait(&condition_variable, &互斥锁);官}- > exit_cond (old_message);}

注意,在enter_cond()之后重复thd->的测试是很重要的。否则,杀死线程可能会在测试thd->在循环条件中被杀死后,在在enter_cond()中注册条件变量和互斥锁之前杀死该线程。在这种情况下,杀死线程不知道这个线程将等待一个条件变量。它只会设置THD::killed。但是,如果我们不再次试验它,即使我们被杀死,我们也会睡着。如果杀死线程在第二次测试之后杀死我们,但仍然在睡觉之前,我们保持互斥锁,它注册在mysys_var中。杀死线程会在向条件变量发出信号之前尝试获取互斥锁。由于互斥锁只在pthread_cond_wait()中隐式释放,所以信号会在正确的位置发生。我们有一个安全的同步。