互斥量
互斥量(互斥锁)
(1) 互斥锁类型: pthread_mutex_t, 定义一个变量相当于创建一把锁
(2) 互斥锁的特点
多个线程传行访问共享数据
(3) 使用互斥锁缺点
效率低
(4) 互斥锁的使用步骤
创建互斥锁: pthread_mutex_t mutex
初始化: pthread_mutex_init(&mutex, NULL)
加锁
pthread_mutex_lock(&mutex)
阻塞线程
pthread_mutex_trylock(&mutex)
如果上锁, 直接返回, 不阻塞, 需要对返回值进行判断
共享数据操作----> 临界区
解锁: pthread_mutex_unlock(&mutex)
, 阻塞在锁上的线程会被唤醒
销毁锁:pthread_mutex_destroy(&mutex)
(5) 互斥锁相关函数
初始化互斥锁: int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
销毁互斥锁: int pthread_mutex_destroy(pthread_mutex_t *mutex);
加锁: 两种加锁方式
int pthread_mutex_lock(pthread_mutex_t *mutex);
没有被上锁, 当前线程会将这把锁锁上
如果加锁的时候发现所已经被锁上, 线程会一直阻塞在这个位置, 锁被打开的时候解除阻塞
int pthread_mutex_trylock(pthread_mutex_t *mutex);
if (pthread_mutex_trylock(&mutex) == 0) {
// 尝试加锁, 并且成功
// 访问共享资源
}
else {
// 错误处理
// 或者等一会, 再次尝试加锁
}
没有被锁上: 当前线程会给这把锁加锁
锁上: 不会阻塞, 返回
解锁int pthread_mutex_unlock(pthread_mutex_t *mutex);
加锁
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#define MAX 100
// 全局变量
int number;
// 创建一把互斥锁
pthread_mutex_t mutex;
void *myfuncA(void *arg) {
int i;
for (i = 0; i < MAX; i++) {
pthread_mutex_lock(&mutex); // 加锁
int cur = number;
cur++;
number = cur;
printf("Thread_A, id = %ld, number = %d\n", pthread_self(), number);
pthread_mutex_unlock(&mutex); // 解锁
usleep(10); // 为使线程A放弃cpu, 加sleep
}
return NULL;
}
void *myfuncB(void *arg) {
int i;
for (i = 0; i < MAX; i++) {
pthread_mutex_lock(&mutex); // 加锁
int cur = number;
cur++;
number = cur;
printf("Thread_B, id = %ld, number = %d\n", pthread_self(), number);
pthread_mutex_unlock(&mutex); // 解锁
usleep(10); // 为使线程B放弃cpu, 加sleep
}
return NULL;
}
int main(void) {
pthread_t p1, p2;
// 初始化互斥锁
pthread_mutex_init(&mutex, NULL);
// 创建线程
pthread_create(&p1, NULL, myfuncA, NULL);
pthread_create(&p2, NULL, myfuncB, NULL);
// 回收
pthread_join(p1, NULL);
pthread_join(p2, NULL);
// 销毁锁
pthread_mutex_destroy(&mutex);
return 0;
}
哲学家吃饭
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
pthread_mutex_t mutex[5];
void *dinner(void *arg) {
int num = (int)arg;
int left, right;
if (num < 4) {
// 前4个人, 右手拿自己的筷子
right = num;
left = num + 1;
}
else if (num == 4) {
// 最后一个人, 右手拿别人筷子
right = 0;
left = num;
}
// 吃饭
while (1) {
// 右手加锁
pthread_mutex_lock(&mutex[right]);
// 尝试抢左手筷子
if (pthread_mutex_trylock(&mutex[left]) == 0) {
// 吃面
printf("%c正在吃面......\n", num+'A');
// 吃完放下筷子
pthread_mutex_unlock(&mutex[left]);
}
// 右手解锁
pthread_mutex_unlock(&mutex[right]);
sleep(rand() % 5);
}
return NULL;
}
int main(void) {
int i;
pthread_t p[5];
for (i = 0; i < 5; i ++)
pthread_mutex_init(&mutex[i], NULL);
for (i = 0; i < 5; i ++)
pthread_create(&p[i], NULL, dinner, (void *)i);
for (i = 0; i < 5; i ++)
pthread_join(p[i], NULL);
for (i = 0; i < 5; i ++)
pthread_mutex_destroy(&mutex[i]);
return 0;
}