互斥锁
互斥锁是为了防止两个线程同时对同一个内存访问时造成的不可知问题而出现的一种机制。
互斥锁机制伪代码
当mutex = 1时解锁,当mutex = 0时加锁
加锁 | 解锁 |
lock: if mutex > 0: mutex = 0; return 0; else: goto lock; | unlock: mutex = 1; return 0; |
互斥锁的原理非常简单,但有一点,为了保证不同线程不会出现同时加锁的现象,加锁操作应该为一个原子操作,也就是需要在单指令周期内完成。
互斥锁相关函数
头文件:
#include "pthread.h"
函数原型 | 函数功能 |
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); int pthread_mutex_destroy(pthread_mutex_t *mutex); pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | 对互斥锁进行初始化/销毁 |
int pthread_mutex_lock(pthread_mutex_t *mutex); | 上锁操作 |
int pthread_mutex_trylock(pthread_mutex_t *mutex); | 尝试上锁 |
int pthread_mutex_unlock(pthread_mutex_t *mutex); | 解锁 |
互斥锁中变量的声明
pthread_mutex_t mutex;
5位哲学家就餐问题
问题描述:
5位哲学家有两个工作,1.思考问题;2.吃饭。并且两个工作不同时进行。他们围坐在一个圆形餐桌上,每两个哲学家中间有一根筷子,要想吃到餐桌中间的饭必须使用两根筷子。
如果所有哲学家之间互不交流,那么就可能出现每个哲学家都右手或左手拿筷子而导致所有人都无法吃饭的问题。
示例程序
#include <iostream>
#include <strings.h>
#include <pthread.h>
#include <unistd.h>
using namespace std;
pthread_mutex_t g_mutex; // 互斥锁
int g_number = 0;
void *work_thread(void *)
{
pthread_t thread_id = pthread_self();
pthread_mutex_lock(&g_mutex);
for(int i = 0; i < 4; i++)
{
g_number++;
}
cout << "hello i am work thread: " << thread_id << " and i change g_number value to: " << g_number << endl;
pthread_mutex_unlock(&g_mutex);
return 0;
}
int main(int argc, char *args[])
{
pthread_t thread_id[2]; // 线程id
int i = 9;
cout << "hello this is a thread mutex test program" << endl;
cout << "begin to init mutex" << endl;
pthread_mutex_init(&g_mutex, NULL);
cout << "mutex init finished" << endl;
g_number = 0;
cout << "now g_number is: " << g_number << endl;
cout << "now i will create 2 thread!" << endl;
pthread_create(&thread_id[0], NULL, &work_thread, (void*)&i);
pthread_create(&thread_id[1], NULL, &work_thread, (void*)&i);
pthread_join(thread_id[0], NULL);
pthread_join(thread_id[1], NULL);
cout << "threads are exit and destroy mutex" << endl;
pthread_mutex_destroy(&g_mutex);
cout << "mutex is destroyed" << endl;
return 0;
}
程序输出:
- hello this is a thread mutex test program
- begin to init mutex
- mutex init finished
- now g_number is: 0
- now i will create 2 thread!
- hello i am work thread: 139753847297792 and i change g_number value to: 4
- hello i am work thread: 139753838905088 and i change g_number value to: 8
- threads are exit and destroy mutex
- mutex is destroyed