32.2 非死锁缺陷 281
11
12 Thread 2::
13 pthread_mutex_lock(&proc_info_lock);
14 thd->proc_info = NULL;
15 pthread_mutex_unlock(&proc_info_lock);
违反顺序缺陷
Lu 等人提出的另一种常见的非死锁问题叫作违反顺序(order violation)。下面是一个简
单的例子。同样,看看你是否能找出为什么下面的代码有缺陷。
1 Thread 1::
2 void init() {
3 ...
4 mThread = PR_CreateThread(mMain, ...);
5 ...
6 }
7
8 Thread 2::
9 void mMain(...) {
10 ...
11 mState = mThread->State;
12 ...
13 }
你可能已经发现,线程 2 的代码中似乎假定变量 mThread 已经被初始化了(不为空)。
然而,如果线程 1 并没有首先执行,线程 2 就可能因为引用空指针奔溃(假设 mThread
初始值为空;否则,可能会产生更加奇怪的问题,因为线程 2 中会读到任意的内存位置
并引用)。
违反顺序更正式的定义是:“两个内存访问的预期顺序被打破了(即 A 应该在 B 之前执
行,但是实际运行中却不是这个顺序)”[L+08]。
我们通过强制顺序来修复这种缺陷。正如之前详细讨论的,条件变量(condition
variables)就是一种简单可靠的方式,在现代代码集中加入这种同步。在上面的例子中,我
们可以把代码修改成这样:
1 pthread_mutex_t mtLock = PTHREAD_MUTEX_INITIALIZER;
2 pthread_cond_t mtCond = PTHREAD_COND_INITIALIZER;
3 int mtInit = 0;
4
5 Thread 1::
6 void init() {
7 ...
8 mThread = PR_CreateThread(mMain, ...);
9
10 // signal that the thread has been created...
11 pthread_mutex_lock(&mtLock);
12 mtInit = 1;
13 pthread_cond_signal(&mtCond);