其他分享
首页 > 其他分享> > VC6.0实现多线程——以火车票售卖为例

VC6.0实现多线程——以火车票售卖为例

作者:互联网

最近在学习C++的过程中了解到多线程,发现“互斥锁”很有用,想着实现一下,无奈对linux系统不是很熟悉,只能在windows上借助VC++6.0试着实现。过程中因为数据类型转换等问题一直做的磕磕绊绊,最终也只是搞出来一个框架,还有很多细节有待完善。先总结下来,留着以后继续探索。

问题说明

程序实现

  1. ticketsSale.h —— 头文件
#include <windows.h>
#include <string>
#include <iostream>

using namespace std;
#define NameLength 20		//车票名字最长为20个字符

//定义结构体用于系统中存储的车票数量和车票名称
typedef struct _Tickets
{
	int tCount;
	char TicketsName[NameLength];

	//结构体对象的默认初始化
	_Tickets():tCount(0)	//数量默认初始化为0
	{
		memset(TicketsName,0,NameLength*(sizeof(char)))	;
	}

}TICKETS;		//结构体的别名为TICKETS

//定义线程入口函数的参数结构体
typedef struct _Thread
{
	TICKETS *ptickets;		//当前系统中的车票信息
	char threadName[NameLength];		//线程名

    _Thread():ptickets(NULL)	//车票信息(结构体对象)初始化为空NULL
    {
        memset(threadName, 0, NameLength * sizeof(char));
    }
}THREADS;		//结构体别名为THREADS

//线程入口函数
DWORD WINAPI SaleTicket(LPVOID lpParameter);		//注意线程函数的定义规范
  1. SaleTicket.cpp —— 线程入口函数
#include <windows.h>
#include <string>
#include <iostream>
#include "ticketsSale.h"

using namespace std;

extern HANDLE g_hMutex;		//外部互斥锁

//线程入口函数
DWORD WINAPI SaleTicket(LPVOID lpParameter)		//注意线程函数的定义规范
{

	// 对传入的参数进行强制类型转换,由无类型指针变为整形数指针
	THREADS * pthread = (THREADS *)lpParameter;  

	//需要处理的车票信息,用指针获取
	//这里用指针获取车票信息,是为了保证多线程之间对车票的处理可以同步
	TICKETS * psaletickets = pthread->ptickets; 

	while(psaletickets->tCount>0)
	{
		//请求获得一个互斥量锁,等待时间为infinite
        WaitForSingleObject(g_hMutex, INFINITE);

		//在获得互斥锁后,车票数量可能已经发生更改,需要重新查询、判断
		if((psaletickets->tCount)>0)
		{
			cout << pthread->threadName << "售出"<< psaletickets->TicketsName<< "的票;";
			cout << "车票编号:" << psaletickets->tCount<<endl;
			psaletickets->tCount--;		//修改后台剩余车票信息
			cout << "剩余车票 "<<psaletickets->tCount << "张 "<<endl;
			cout <<endl;
		}
		else		//已经没有车票
		{
			cout << "出票失败,已经没有余票! "<<endl;
		}
	    Sleep(100);
	    
        //操作完成,释放互斥量锁
        ReleaseMutex(g_hMutex);
	}
	
	return 0;

}
  1. main.cpp —— 主程序入口
#include <windows.h>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <sstream>
#include "ticketsSale.h"

using namespace std;

HANDLE g_hMutex;	//这是一个全局变量,在main函数外面声明才能在其他地方引用

int main()
{
	//创建一个互斥量用于线程间同步
	g_hMutex = CreateMutex(NULL, FALSE, NULL);

	//初始化火车票信息
    TICKETS ticket;
    ticket.tCount = 100;
    strcpy(ticket.TicketsName, "北京-->赣州");

	const int ThreadsNum = 5;		//共有5个线程可以操作数据

	//数组声明中,下标必须为常量,因此ThreadsNum声明为const
	THREADS threadSale[ThreadsNum];		//线程结构体数组 
    HANDLE hThread[ThreadsNum];		//用于保存创建线程后的返回句柄

	//依次创建5个线程
	for(int i =0;i<ThreadsNum;i++)
	{
		//构建线程入口函数需要传入的参数结构体
		(threadSale[i]).ptickets = &ticket;	

		//用stringstream流实现数字转字符串
		stringstream s;
		s << i;
		string name = "窗口"+s.str();

		strcpy(threadSale[i].threadName,name.c_str());

		//创建线程
        hThread[i] = CreateThread(NULL, NULL, SaleTicket, &threadSale[i], 0, NULL);
	}

	for(int j = 0;j<ThreadsNum;j++)
	{	        
		//关闭线程
        CloseHandle(hThread[j]);
	}

	system("pause");
	return 0;
}
  1. 运行结果
窗口0售出北京-->赣州的票;车票编号:100
剩余车票 99张

请按任意键继续. . . 窗口1售出北京-->赣州的票;车票编号:99
剩余车票 98张

窗口2售出北京-->赣州的票;车票编号:98
剩余车票 97张

窗口3售出北京-->赣州的票;车票编号:97
剩余车票 96张

窗口4售出北京-->赣州的票;车票编号:96
剩余车票 95张

窗口0售出北京-->赣州的票;车票编号:95
剩余车票 94张
  1. 大致实现了多线程同步的功能,可是main线程和各个子线程是一起执行的,跟想要的结果不一样。理想情况下,main线程应该独立于子线程。怎么做到,留着以后进一步探索喽!

标签:include,窗口,函数,VC6.0,为例,互斥,线程,车票,多线程
来源: https://blog.csdn.net/sleeping2dogs/article/details/99641469