//有缺陷的售票系统
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<assert.h>
//#pragma comment(lib, "pthreadVC2.lib")
int tickt = 100;
void * route(void * arg)
{
char *id = (char *)arg;
while (1)
{
if(tickt > 0)
{
sleep(1);
printf("cout %s sells ticks:%d\n", id,tickt);
tickt;
}
else
{
break;
}
}
return NULL;
}
int main(void)
{
pthread_t t1, t2, t3, t4;
int res1 = pthread_create(&t1, NULL, route, (void *)"thread 1");
assert(res1 == 0);
int res2 = pthread_create(&t2, NULL, route, (void *)"thread 2");
assert(res2 == 0);
int res3 = pthread_create(&t3, NULL, route, (void *)"thread 3");
assert(res3 == 0);
int res4 = pthread_create(&t4, NULL, route, (void *)"thread 4");
assert(res4 == 0);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_join(t4, NULL);
printf("cout mian\n");
return 0;
}
ps:
- join会阻塞调用的线程,直到thread指定的线程结束(串行,类似函数调用) 可用于得到指定线程结束信息(状态),对其他线程不产生影响,除非你将创建和join放在一起,增加关联性,使得CPU无法并行处理。
- if语句判读为真以后,代码可以并发的切换(甚至并行)其他线程
- sleep 这个模拟漫长的业务过程中,可能有多个线程会进入该临界资源
- –ticket操作本身不是一个原子操作(需要3条指令完成);
load:将共享变量ticket从内存加载到寄存器
update:更新寄存器里面的值,执行-1操作。
store:将寄存器里的新值,从寄存器写回共享变量ticket的内存地址。
解决:
- 代码必须要有互尽行为:当代码进入临界区执行时,不允许其他线程进入该临界区。
- 如果多个线程同时要求执行临界区的代码,并且临界区没有线程在执行,那么只能允许一个线程进入该临界区。
- 如果线程不在临界区中执行,那么该线程不能阻止其他线程进入临界区。
//互斥量实现的售票系统
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<assert.h>
//#include<semaphre.h>
//#pragma comment(lib, "pthreadVC2.lib")
int tickt = 100;
pthread_mutex_t mutex;
void * route(void * arg)
{
char *id = (char *)arg;
while (1)
{
usleep(1000);//需要一个时间来使CPU调动线程的时间片消耗完,否则当执行线程时间片到而退出但由于临界资源是被锁住的其他线程无法访问,即会造成只有一个线程会调用资源的问题。
pthread_mutex_lock(&mutex);
if(tickt > 0)
{
usleep(1000);
printf("cout %s sells ticks:%d\n", id,tickt);
tickt--;
pthread_mutex_unlock(&mutex);
}
else
{
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
break;
}
}
return NULL;
}
int main(void)
{
pthread_mutex_init(&mutex, NULL);
pthread_t t1, t2, t3, t4;
int res1 = pthread_create(&t1, NULL, route, (void *)"thread 1");
assert(res1 == 0);
int res2 = pthread_create(&t2, NULL, route, (void *)"thread 2");
assert(res2 == 0);
int res4 = pthread_create(&t4, NULL, route, (void *)"thread 4");
assert(res4 == 0);
int res3 = pthread_create(&t3, NULL, route, (void *)"thread 3");
assert(res3 == 0);
pthread_join(t4,NULL);
pthread_mutex_destroy(&mutex);
printf("cout mian\n");
pthread_exit(NULL);
return 0;
}