有时候,很多变量都需要在线程间共享,这样的变量称为共享变量,可以通过数据的共享,完成线程之间的交互。多个线程并发的操作共享变量,会带来一些问题。看下面的一段代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int ticket = 100;
void* route(void* arg)
{
char* id = (char*)arg;
while (1) {
if (ticket > 0) {
usleep(1000);
printf("%s sells ticket:%d\n", id, ticket);
ticket--;
}
else {
break;
}
}
}
int main(void)
{
pthread_t t1, t2, t3, t4;
pthread_create(&t1, NULL, route, "thread 1");
pthread_create(&t2, NULL, route, "thread 2");
pthread_create(&t3, NULL, route, "thread 3");
pthread_create(&t4, NULL, route, "thread 4");
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_join(t4, NULL);
}
//一次执行结果:
thread 4 sells ticket : 100
...
thread 4 sells ticket : 1
thread 2 sells ticket : 0
thread 1 sells ticket : -1
thread 3 sells ticket : -2
为什么可能无法获得争取结果?
由上面的汇编图可以看出来,操作并不是原子的,而是对应三条汇编指令:
要解决以上问题,需要做到三点:
所谓互斥量,就是同一时刻只运行一个线程或者进程访问共享资源,如下图所示:
初始化互斥量有两种方法:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrictattr);
参数:
mutex:要初始化的互斥量
attr:NULL(一般情况)
销毁互斥量需要注意:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
返回值:成功返回0,失败返回错误号
调用 pthread_ lock 时,可能会遇到以下情况: