多线程-------线程的同步与互斥
程序员文章站
2022-05-05 10:29:50
...
一、什么是互斥量(mutex)
先来看一段代码:操作共享变量会有问题的售票系统
Makefile
mypthread.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int ticket = 100;
void *sell_ticket(void *arg)
{
char *id = (char*)arg;
while(1)
{
if(ticket > 0)
{
usleep(1000);
printf("%s get ticket,id is %d\n",(char*)arg,ticket);
ticket--;
}
else
{
break;
}
}
}
int main()
{
pthread_t t1,t2,t3,t4;
pthread_create(&t1,NULL,sell_ticket, "thread 1 is runing");
pthread_create(&t2,NULL,sell_ticket, "thread 2 is runing");
pthread_create(&t3,NULL,sell_ticket, "thread 3 is runing");
pthread_create(&t4,NULL,sell_ticket, "thread 4 is runing");
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_join(t4, NULL);
return 0;
}
运行之:
线程不断买票,买到后面时出现-1,-2
-1 -2意味着什么 意味着票务系统出错了,(数据不一致问题:临界资源有可能在同一时间被多个线程访问,无法保证原子性)
- 怎样解决:加锁:实现互斥(1、保证一个线程在访问临界资源的时候,其他线程不能访问;2、如果线程不在临界区中执行,那么该线程不能阻止其他线程进入临界区)
图示一下互斥量(加的锁:在临界区前后 加锁解锁)
1、互斥量的相关接口
(1)初始化互斥量
* 方法一:静态分配
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
* 方法二:动态分配
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
//参数
mutex:要初始化的互斥量
attr:NULL
全局变量为什么能被线程看到:线程之间资源共享
(2)销毁互斥量
#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);
// 返回值
成功返回0;失败返回错误码
(3)互斥量加锁和解锁(加锁和解锁是原子的)
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
// 返回值:成功返回0;失败返回错误码
调用pthread_mutex_lock时遇到的情况:
(1)互斥量处于未锁状态,该函数会将互斥量锁定,同时返回成功
(2)发起函数调用时,其他线程已经锁定互斥量,或者存在其他线程同时申请互斥量,但没有竞争到互斥量,辣么pthread_mutex_lock调用会陷入阻塞,等待互斥量解锁
改进一下刚开始的票务系统的代码:
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int ticket = 100;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *sell_ticket(void *arg)
{
char *id = (char*)arg;
while(1)
{
// 给临界区加锁
pthread_mutex_lock(&lock);
if(ticket > 0)
{
usleep(1000);
printf("%s get ticket,id is %d\n",(char*)arg,ticket);
ticket--;
pthread_mutex_unlock(&lock);
}
else
{
pthread_mutex_unlock(&lock);
break;
}
}
}
int main()
{
pthread_t t1,t2,t3,t4;
pthread_create(&t1,NULL,sell_ticket, "thread 1 is runing");
pthread_create(&t2,NULL,sell_ticket, "thread 2 is runing");
pthread_create(&t3,NULL,sell_ticket, "thread 3 is runing");
pthread_create(&t4,NULL,sell_ticket, "thread 4 is runing");
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_join(t4, NULL);
// 销毁
pthread_mutex_destroy(&lock);
return 0;
}
运行之:
上一篇: 安装好vagrant后,用“运行”打开的时候总是闪退。。。。为什么呢
下一篇: 线程同步与互斥