Linux下多线程模拟停车场停车
标签:clu sign char efi range second 结构 == one
#include
#includestring.h>
#include
#include
#include#define ONE_SECOND 1000000
#define RANGE 10
#define PERIOD 2
#define NUM_THREADS 4
typedef struct
{
int *carpark; //用一个数组来模拟停车场停车位
int capacity; //停车场的车辆容量
int occupied; //停车场现有的车辆数目
int nextin; //下一个进来的车的位置(用carpark数组代表的下标表示)
int nextout; //下一个取走的车的停车位置
int cars_in; //记录停车场进入车辆的总和
int cars_out; //记录从停车场开出去的车辆总和
pthread_mutex_t lock; //互斥量,保护该结构中的数据被线程互斥的方式使用
pthread_cond_t space; //条件变量 描述停车场是否有空位置
pthread_cond_t car; //条件变量 描述停车场是否有车
pthread_barrier_t bar; //线程屏障
}cp_t;
static void initialise(cp_t *cp,int size)
{
cp->occupied = cp->nextin = cp->nextout = cp->cars_in = cp->cars_out = 0;
cp->capacity = size;
cp->carpark = (int *)malloc(cp->capacity * sizeof(*cp->carpark));
//初始化线程屏障,NUM_THREADS表示等待 NUM_THREADS=4个线程同步执行
pthread_barrier_init(&cp->bar,NULL,NUM_THREADS);
if(cp->carpark == NULL)
{
perror("malloc()");
exit(1);
}
srand((unsigned int )getpid());
pthread_mutex_init(&cp->lock,NULL); //初始化停车场的锁
pthread_cond_init(&cp->space,NULL); //初始化描述停车场是否有空位的条件变量
pthread_cond_init(&cp->car,NULL); //初始化描述停车场是否有车的条件变量
}
static void* car_in_handler(void* carpark_in)
{
cp_t *temp;
unsigned int seed;
temp = (cp_t *)carpark_in;
//pthread_barrier_wait 函数表示,线程已完成工作,等到其他线程赶来
pthread_barrier_wait(&temp->bar);
while(1)
{
//将线程挂起一段时间,模拟车辆到来的随机性
usleep(rand_r(&seed) % ONE_SECOND);
pthread_mutex_lock(&temp->lock);
//循环等待知道有停车位
while(temp->occupied == temp->capacity)
pthread_cond_wait(&temp->space,&temp->lock);
//插入一辆车,用随机数标识
temp->carpark[temp->nextin] = rand_r(&seed) % RANGE;
temp->occupied++;
temp->nextin++;
temp->nextin %= temp->capacity;
temp->cars_in++;
//可能有的人在等车可取,发送temp->car条件变量
pthread_cond_signal(&temp->car);
pthread_mutex_unlock(&temp->lock);
}
return ((void*)NULL);
}
static void* car_out_handler(void *carpark_out)
{
cp_t *temp;
unsigned int seed;
temp = (cp_t *)carpark_out;
pthread_barrier_wait(&temp->bar);
for(;;)
{
usleep(rand_r(&seed) % ONE_SECOND);
pthread_mutex_lock(&temp->lock);
/*
获得锁后访问temp->occupied 变量,此时如果车辆数为0 (occupied == 0)
pthread_cond_wait 进行的操作就是忙等,释放锁(&temp->lock)供其他路线使用
知道temp->car条件改变时再次将锁锁住
*/
while(temp->occupied == 0)
{
pthread_cond_wait(&temp->car,&temp->lock);
}
temp->occupied--;
temp->nextout++;
temp->nextout %= temp->capacity;
temp->cars_out++;
pthread_cond_signal(&temp->space);
pthread_mutex_unlock(&temp->lock);
}
return ((void *)NULL);
}
static void *monitor(void *carpark_in)
{
cp_t *temp;
temp = (cp_t *)carpark_in;
for(;;)
{
sleep(PERIOD);
pthread_mutex_lock(&temp->lock);
printf("Delta:%d\n",temp->cars_in - temp->cars_out - temp->occupied);
printf("Number of cars in carpark:%d\n",temp->occupied);
pthread_mutex_unlock(&temp->lock);
}
return ((void *)NULL);
}
int main(int argc,char **argv)
{
printf("main version 1.0\n");
if(argc != 2)
{
printf("Usage :%s carparksize\n",argv[0]);
exit(1);
}
cp_t outpark;
initialise(&outpark,atoi(argv[1])); //初始化停车场数据结构
pthread_t car_in,car_out,m; //定义线程变量
pthread_t car_in2,car_out2;
/***
创建往停车场停车线程(生成者1)
创建从停车场取车线程(消费者1)
创建往停车场停车线程(生成者2)
创建从停车场取车线程(消费者2)
创建用于监控停车场状况的线程
***/
pthread_create(&car_in,NULL,car_in_handler,(void*)&outpark);
pthread_create(&car_out,NULL,car_out_handler,(void*)&outpark);
pthread_create(&car_in2,NULL,car_in_handler,(void*)&outpark);
pthread_create(&car_out2,NULL,car_out_handler,(void*)&outpark);
pthread_create(&m,NULL,monitor,(void*)&outpark);
//pthread_join的第二个参数为NULL,表示不关心线程返回状态,仅仅等待指定线程的终止
pthread_join(car_in,NULL);
pthread_join(car_out,NULL);
pthread_join(car_in2,NULL);
pthread_join(car_out2,NULL);
pthread_join(m,NULL);
return 0;
}
Linux下多线程模拟停车场停车
标签:clu sign char efi range second 结构 == one
原文地址:https://www.cnblogs.com/wanghao-boke/p/11613071.html
评论