C语言之模拟卖票

用共享内存和信号量去模拟一个卖火车票的程序。

 

首先建立一个共享内存和一个信号量,并初始化信号量,然后用一个指针指向共享内存。然后调用一个卖票的函数,去模拟卖票的功能。

头文件
#ifndef __SEMAPHORE_H__
#define __SEMAPHORE_H__

union semun  //定义的共同体 
{
	int              val;    /* Value for SETVAL */
	struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
	unsigned short  *array;  /* Array for GETALL, SETALL */
	struct seminfo  *__buf;  /* Buffer for IPC_INFO
							   (Linux specific) */
};

//信号量的初始化
int sem_init(int sem_id)
{
	union semun sem;
	sem.val = 1;
	int ret = semctl(sem_id, 0, SETVAL, sem);
	return ret;
}

//信号量的P操作
int sem_p(int sem_id)
{
	struct sembuf sem;
	sem.sem_num = 0;
	sem.sem_op = -1;
	sem.sem_flg = SEM_UNDO;
	int ret = semop(sem_id, &sem, 1);
	return ret;
}

//信号量的V操作
int sem_v(int sem_id)
{
	struct sembuf sem;
	sem.sem_num = 0;
	sem.sem_op = 1;
	sem.sem_flg = SEM_UNDO;
	int ret = semop(sem_id, &sem, 1);
	return ret;
}

//信号量的销毁
int sem_del(int sem_id)
{
	int ret = semctl(sem_id, 0, IPC_RMID);
	return ret;
}

#endif //__SEMAPHORE_H__

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/sem.h>
#include "semaphore.h"

typedef struct _shm
{
	int flag;
	int ticket;
}SHM;

void sell_ticket(SHM *pshm, int ret)  //卖票函数
{
	int time;
	while(1)
	{
		time = rand() % 10 + 1;
		usleep(time * 100000);   //卖完一张票以后随机休眠0.几秒,模拟卖票窗口
		sem_p (ret);    //信号量的P操作,让一个卖票窗口进入内存去“取票”
		
		if(pshm->ticket == 0)   //票卖完,则退出程序
		{
			sem_v (ret);
			break;
		}
		printf("卖掉一张票,座位号是:%d\n",pshm->ticket);
		pshm->ticket--;    //卖出一张票,总数减一
		sem_v (ret);  //信号量的V操作,让窗口重新去内存里去“取票”
	}
	printf("票已卖完\n");
}


int main(int argc, int **argv)
{
	srand((unsigned)time(NULL));   //产生随机数
	int shmid = shmget((key_t)1234, sizeof(SHM), 0666 | IPC_CREAT);
	if(shmid == -1)
	{
		perror("shmget");
		return -1;
	}
	
	int ret = semget((key_t)5678, 1, 0666 | IPC_CREAT);  //创建共享内存
	if(ret == -1)
	{
		perror("semget");
		return -1;
	}
	
	SHM *pshm = shmat(shmid, NULL, 0);  //映射到共享内存
	if(pshm == (SHM *)-1)
	{
		perror("shmat");
		return -1;
	}
	
	
	if(argc == 2)   //初始化
	{
		pshm->ticket = 100;
		sem_init(ret);
	}
	
	sell_ticket(pshm, ret);  //开始卖票
	
	if(argc == 2)
	{
		shmdt(pshm);   //解除共享内存
		
		shmctl(shmid, IPC_RMID, NULL);   //删除共享内存
		
		sem_del(ret);   //删除信号量
	}
	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值