问题的根源：不受控制的调度

mov     0x8049a1c, %eax
add     $0x1, %eax mov %eax, 0x8049a1c  这段指令序列很简单，CPU 可以在执行到 1、2、3 的任意时候终端当前线程的执行流而去执行另外一个，因此会导致一个线程的当前操作还没完成就被另一个线程修改了。 原子操作 为了解决这个问题，我们想借助硬件的帮助。 比如说，加一个数，memory-add 0x8049a1c,$0x1，让硬件保证它只有一条指令，而且完成这条指令所需的CPU 时钟内不能被中断，我们把这种行为叫做 原子的（atomically）

• A critical section is a piece of code that accesses a shared resource, usually a variable or data structure.
• A race condition arises if multiple threads of execution enter the critical section at roughly the same time; both attempt to update the shared data structure, leading to a surprising (and perhaps undesirable) outcome.
• An indeterminate program consists of one or more race conditions; the output of the program varies from run to run, depending on which threads ran when. The outcome is thus not deterministic, something we usually expect from computer systems.
• To avoid these problems, threads should use some kind of mutual exclusion primitives; doing so guarantees that only a single thread ever enters a critical section, thus avoiding races, and resulting in deterministic program outputs.

线程创建

int pthread_create(..., // first two args are the same
void * ( * start_routine)(int),
int arg);


线程完成

int pthread_join(pthread_t thread, void ** value_ptr);


锁

int pthread_mutex_lock(pthread_mutex_t * mutex);    // 加锁



pthread_mutex_t lock;
x = x + 1; // or whatever your critical section is pthread_mutex_unlock(&lock);

• 如果没有其他线程拥有 lock，当前线程会获得这把锁，并且进入 critical seciton
• 如果其他线程已经拥有了此 lock，想获取此 lock 的线程不会从这函数中返回，直到它能获取到锁为止
• 不一定呆呆的等待，也可以设置一个超时时间。

int rc = pthread_mutex_init(&lock, NULL);
assert(rc == 0); // always check success!


// Use this to keep your code clean but check for failures
// Only use if exiting program is OK upon failure
assert(rc == 0);
}


int pthread_mutex_trylock(pthread_mutex_t * mutex);



条件变量 Condition Variables

int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex);



pthread_cond_wait() 会使得调用当前线程的休眠（sleep），直到其他线程完成某些任务，通过 cond 变量通知到它，然后把它唤醒。

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;



Pthread_mutex_lock(&lock);