大家好,今天主要聊一聊,如何使用Linux系统间通信实现售票的方法。
第一:代码实现:
//Linux系统售票方法
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
typedef struct
{
char menu_choice; //菜单选择
int stand_ticket; //站票数
int seat_ticket; //坐票数
FILE *fp; //指向存储用户账号密码的文件
int userLogin[2]; //用户登录帐号和密码
int user_stand; //用户站票数
int user_seat; //用户坐票数
}STR;
pthread_mutex_t lock; //互斥锁
void *menu(void *arg);//菜单线程
void *sale(void *arg);//售票线程
void *refund(void *arg);//退票线程
void *login(void *arg);//登录线程
void *enroll(void *arg);//注册线程
int main(int argc,const char *argv[])
{
STR arg = {
0,
5,
5,
NULL,
{0},
0,
0
};//参数包
int i;
pthread_t tid[5];//线程号数组
pthread_mutex_t lock;//互斥锁
int ret;
FILE *temp_p;
char t[20] = {0};
char ch;
if((arg.fp = fopen("id_password.txt","a+b")) == NULL)
{
fprintf(stderr,"open file failed\r\n");
exit(EXIT_FAILURE);
}
//互斥锁创建
pthread_mutex_init(&lock,NULL);
//线程创建
pthread_create(&tid[0],NULL,menu,(void *)&arg); //创建菜单线程
pthread_create(&tid[1],NULL,sale,(void *)&arg); //创建售票线程
pthread_create(&tid[2],NULL,refund,(void *)&arg); //创建退票线程
pthread_create(&tid[3],NULL,login,(void *)&arg); //创建登录线程
pthread_create(&tid[4],NULL,enroll,(void *)&arg); //创建注册线程
//等待线程结束
for(i = 0;i < 5;i++)
{
pthread_join(tid[i],NULL);
}
if(arg.userLogin[0] != 0)
{
if((temp_p = fopen("temp.txt","w+b")) == NULL)
{
fprintf(stderr,"open file failed\r\n");
exit(EXIT_FAILURE);
}
fprintf(temp_p,"%d %d %d %d\r\n",arg.userLogin[0],arg.userLogin[1],arg.user_seat,arg.user_stand);
rewind(arg.fp);
while(!feof(arg.fp))
{
fgets(t,20,arg.fp);
sscanf(t," %d",&i);
if(i != arg.userLogin[0])
{
fputs(t,temp_p);
}
}
rewind(temp_p);
fclose(arg.fp);
if((arg.fp = fopen("id_password.txt","w+b")) == NULL)
{
fprintf(stderr,"open file failed\r\n");
exit(EXIT_FAILURE);
}
while((ch = fgetc(temp_p))!=EOF)
{
fputc(ch,arg.fp);
}
fclose(temp_p);
}
fclose(arg.fp);
pthread_exit(NULL);
exit(EXIT_SUCCESS);
return 0;
}
void *menu(void *arg)//菜单线程
{
usleep(10);//挂起(每个线程刚开始都需要挂起,根据挂起时间不同决定哪个线程先运行)
STR *argv = (STR *)arg;//强转
int flag = 1;
while(1)
{
pthread_mutex_lock(&lock);
while(1)
{
if(flag)
{
system("clear");
flag = 0;
}
printf("******************主菜单*************************\n"
" (a) 登录账户\t(b) 注册账户\n"
" (c) 购票\t(d) 退票\n"
" (q) 退出\n"
"**********************************************\n\n"
"请输入选项:");
scanf(" %c",&argv->menu_choice);
if((argv->menu_choice < 'a'|| argv->menu_choice > 'd')&& argv->menu_choice != 'q')
{
printf("请输入 a - d 或者 q\n");
continue;
}
if(argv->userLogin[0] == 0 && argv->menu_choice != 'q' && argv->menu_choice != 'a' && argv->menu_choice != 'b')
{
printf("请先登录或注册账户!\r\n");
continue;
}
break;
}
pthread_mutex_unlock(&lock);//解锁
if(argv->menu_choice == 'q')
{
pthread_exit(NULL);
}
usleep(200);//挂起
}
}
void *sale(void *arg)//售票线程
{
usleep(200);
STR *argv = (STR *)arg;//强转
while(1)
{
while(1)
{
pthread_mutex_lock(&lock);
if(argv->menu_choice == 'q')
{
pthread_mutex_unlock(&lock);//解锁
pthread_exit(NULL);
}
if(argv->menu_choice == 'c')
{
break;
}
pthread_mutex_unlock(&lock);//解锁
usleep(200);
}
system("clear");
printf("**********************欢迎来到售票窗口*********************\n"
" 总余票:%d\t 坐票:%d\t\t站票:%d\r\n"
" 您的账户:\r\n"
" 坐票:%d\t\t站票:%d\r\n"
" (a) 购买坐票\t\t(b) 购买站票\r\n"
" (q) 退出到主菜单\r\n"
"**********************************************************\n\n"
"请输入选项:",
argv->stand_ticket+argv->seat_ticket,argv->seat_ticket,argv->stand_ticket,
argv->user_seat, argv->user_stand);
char choice = 0;
int num = 0;
while(scanf(" %c",&choice)!=1||(choice != 'a' && choice != 'b' && choice != 'q'))
{
printf("请输入a/b/q!\r\n");
}
if(choice == 'a')
{
if(argv->seat_ticket == 0)
{
printf("坐票余票不足,请重新输入:\r\n");
continue;
}
printf("请输入购买坐票的数量:\r\n");
while(scanf(" %d",&num)!=1 || argv->seat_ticket-num < 0)
{
printf("请输入正确的数量:\r\n");
while(getchar()!='\n')
{
continue;
}
}
argv->seat_ticket -= num;
argv->user_seat += num;
printf("购票成功\r\n");
}else if(choice == 'b')
{
if(argv->stand_ticket == 0)
{
printf("站票余票不足,请重新输入:\r\n");
continue;
}
printf("请输入购买站票的数量:\r\n");
while(scanf(" %d",&num)!=1 || argv->stand_ticket-num < 0)
{
printf("请输入正确的数量:\r\n");
while(getchar()!='\n')
{
continue;
}
}
argv->stand_ticket -= num;
argv->user_stand += num;
printf("购票成功\r\n");
}
pthread_mutex_unlock(&lock);//解锁
usleep(200);
}
}
void *refund(void *arg)//退票线程
{
usleep(200);
STR *argv = (STR *)arg;//强转
while(1)
{
while(1)
{
pthread_mutex_lock(&lock);
if(argv->menu_choice == 'q')
{
pthread_mutex_unlock(&lock);//解锁
pthread_exit(NULL);
}
if(argv->menu_choice == 'd')
{
break;
}
pthread_mutex_unlock(&lock);//解锁
usleep(200);
}
system("clear");
printf("**********************欢迎来到退票窗口*********************\n"
" 当前账户余票:%d\t 坐票:%d\t\t站票:%d\r\n"
" (a) 退坐票\t\t(b) 退站票\r\n"
" (q) 退出到主菜单\r\n"
"**********************************************************\n\n"
"请输入选项:",
argv->user_stand+argv->user_seat,argv->user_seat, argv->user_stand);
char choice = 0;
int num = 0;
while(scanf(" %c",&choice)!=1||(choice != 'a' && choice != 'b' && choice != 'q'))
{
printf("请输入a/b/q!\r\n");
}
if(choice == 'a')
{
if(argv->user_seat == 0)
{
printf("您的坐票不足,请重新输入:\r\n");
continue;
}
printf("请输入退坐票的数量:\r\n");
while(scanf(" %d",&num)!=1 || argv->user_seat-num < 0)
{
printf("请输入正确的数量:\r\n");
while(getchar()!='\n')
{
continue;
}
}
argv->user_seat -= num;
argv->seat_ticket += num;
printf("退票成功\r\n");
}else if(choice == 'b')
{
if(argv->user_stand == 0)
{
printf("您的站票不足,请重新输入:\r\n");
continue;
}
printf("请输入退站票的数量:\r\n");
while(scanf(" %d",&num)!=1 || argv->user_stand-num < 0)
{
printf("请输入正确的数量:\r\n");
while(getchar()!='\n')
{
continue;
}
}
argv->user_stand -= num;
argv->stand_ticket += num;
printf("退票成功\r\n");
}
pthread_mutex_unlock(&lock);//解锁
usleep(200);
}
}
void *enroll(void *arg)//注册线程
{
usleep(200);
STR *argv = (STR *)arg;//强转
while(1)
{
while(1)
{
pthread_mutex_lock(&lock);
if(argv->menu_choice == 'q')
{
pthread_mutex_unlock(&lock);//解锁
pthread_exit(NULL);
}
if(argv->menu_choice == 'b')
{
break;
}
pthread_mutex_unlock(&lock);//解锁
usleep(200);
}
system("clear");
printf("**********************欢迎来到注册窗口*********************\n"
" 请输入注册账号(6位数字):");
int id = 0;
int pwd = 0;
int temp = 0;
int flag = 0;
while(scanf(" %d",&id)!=1 || id / 100000 == 0)
{
printf("请输入正确的账号(6位数字):\r\n");
while(getchar()!='\n')
{
continue;
}
}
rewind(argv->fp);
while(!feof(argv->fp))
{
fscanf(argv->fp," %d",&temp);
if(temp == id)
{
printf("该用户名已存在!\r\n");
flag = 1;
break;
}
}
if(!flag)
{
printf(" 请输入密码(6位数字):");
while(scanf(" %d",&pwd)!=1 || pwd / 100000 == 0)
{
printf("请输入正确的密码(6位数字):\r\n");
while(getchar()!='\n')
{
continue;
}
}
fseek(argv->fp,0,SEEK_END);
fprintf(argv->fp,"%d %d ",id,pwd);
printf("注册成功\r\n");
}
pthread_mutex_unlock(&lock);//解锁
usleep(200);
}
}
void *login(void *arg)//登录线程
{
usleep(200);
STR *argv = (STR *)arg;//强转
while(1)
{
while(1)
{
pthread_mutex_lock(&lock);
if(argv->menu_choice == 'q')
{
pthread_mutex_unlock(&lock);//解锁
pthread_exit(NULL);
}
if(argv->menu_choice == 'a')
{
break;
}
pthread_mutex_unlock(&lock);//解锁
usleep(200);
}
system("clear");
printf("**********************用户登录*********************\n"
" 请输入账号:");
int id = 0;
int pwd = 0;
int temp = 0;
int flag = 0;
while(scanf(" %d",&id)!=1 || id / 100000 == 0)
{
printf("请输入正确的账号(6位数字):\r\n");
while(getchar()!='\n')
{
continue;
}
}
rewind(argv->fp);
while(!feof(argv->fp))
{
fscanf(argv->fp," %d",&temp);
if(temp == id)
{
flag = 1;
break;
}
}
if(!flag)
{
printf("用户名错误或不存在!\r\n");
}
if(flag)
{
printf(" 请输入密码:");
while(scanf(" %d",&pwd)!=1 || pwd / 100000 == 0)
{
printf("请输入正确的密码(6位数字):\r\n");
while(getchar()!='\n')
{
continue;
}
}
fscanf(argv->fp," %d",&temp);
if(temp == pwd)
{
printf("登录成功\r\n");
argv->userLogin[0] = id;
argv->userLogin[1] = pwd;
for(int i = 0;i < 2;i++)
{
fscanf(argv->fp,"%d",&argv->user_seat);
fscanf(argv->fp,"%d\n",&argv->user_stand);
}
}else
{
printf("密码错误\r\n");
}
}
pthread_mutex_unlock(&lock);//解锁
usleep(200);
}
}