Linux系统间通信实现售票的方法

简介: 大家好,今天主要聊一聊,如何使用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);
    }
}

第二:实验效果:

b2ec6b490dae4ec188e47825ba440a11.png

微信图片_20221208204231.png

售票系统

目录
相关文章
|
5天前
|
Linux 应用服务中间件 Shell
linux系统服务二!
本文详细介绍了Linux系统的启动流程,包括CentOS 7的具体启动步骤,从BIOS自检到加载内核、启动systemd程序等。同时,文章还对比了CentOS 6和CentOS 7的启动流程,分析了启动过程中的耗时情况。接着,文章讲解了Linux的运行级别及其管理命令,systemd的基本概念、优势及常用命令,并提供了自定义systemd启动文件的示例。最后,文章介绍了单用户模式和救援模式的使用方法,包括如何找回忘记的密码和修复启动故障。
22 5
linux系统服务二!
|
5天前
|
Linux 应用服务中间件 Shell
linux系统服务!!!
本文详细介绍了Linux系统(以CentOS7为例)的启动流程,包括BIOS自检、读取MBR信息、加载Grub菜单、加载内核及驱动程序、启动systemd程序加载必要文件等五个主要步骤。同时,文章还对比了CentOS6和CentOS7的启动流程图,并分析了启动流程的耗时。此外,文中还讲解了Linux的运行级别、systemd的基本概念及其优势,以及如何使用systemd管理服务。最后,文章提供了单用户模式和救援模式的实战案例,帮助读者理解如何在系统启动出现问题时进行修复。
23 3
linux系统服务!!!
|
5天前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
20 2
|
7天前
|
Ubuntu Linux Shell
Linux 系统中的代码类型或脚本类型内容
在 Linux 系统中,代码类型多样,包括 Shell 脚本、配置文件、网络配置、命令行工具和 Cron 定时任务。这些代码类型广泛应用于系统管理、自动化操作、网络配置和定期任务,掌握它们能显著提高系统管理和开发的效率。
|
8天前
|
Linux Shell 数据库
文件查找是Linux用户日常工作的重要技能介绍了几种不常见的文件查找方法
文件查找是Linux用户日常工作的重要技能。本文介绍了几种不常见的文件查找方法,包括使用`find`和`column`组合、`locate`和`mlocate`快速查找、编写Shell脚本、使用现代工具`fd`、结合`grep`搜索文件内容,以及图形界面工具如`Gnome Search Tool`和`Albert`。这些方法能显著提升文件查找的效率和准确性。
28 2
|
10天前
|
关系型数据库 MySQL Linux
Linux系统如何设置自启动服务在MySQL数据库启动后执行?
【10月更文挑战第25天】Linux系统如何设置自启动服务在MySQL数据库启动后执行?
55 3
|
11天前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
17天前
|
运维 安全 Linux
Linux中传输文件文件夹的10个scp命令
【10月更文挑战第18天】本文详细介绍了10种利用scp命令在Linux系统中进行文件传输的方法,涵盖基础文件传输、使用密钥认证、复制整个目录、从远程主机复制文件、同时传输多个文件和目录、保持文件权限、跨多台远程主机传输、指定端口及显示传输进度等场景,旨在帮助用户在不同情况下高效安全地完成文件传输任务。
119 5
|
16天前
|
Linux
Linux系统之expr命令的基本使用
【10月更文挑战第18天】Linux系统之expr命令的基本使用
51 4
|
3天前
|
缓存 监控 Linux