天天看點

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);
    }
}      

第二:實驗效果:

Linux系統間通信實作售票的方法

繼續閱讀