《面试宝典》例题之模拟火车站售票程序

本文记录了面试宝典第五版第284页的例题,涉及创建两个线程来模拟火车站售票程序,每个窗口售票间隔1秒,且不能同时售票。在C语言中实现多线程,探讨线程的进入点函数和线程结束过程。实际运行结果与预期不同,出现了线程竞态现象。
摘要由CSDN通过智能技术生成

面试宝典第五版284页例题6

题目:创建两个线程模拟火车站两个窗口售票程序,窗口售票时间为1s,两个窗口不能同时售票

之前没写过C的多线程程序,将这道题记录于此以便日后翻看。每当程序被初始化的时候,系统就要创建一个主线程。该线程与C/C++运行期库的启动代码一道开始运行,启动代码则调用进入点函数,并且继续运行直到进入点函数返回并且C/C++运行期库的启动代码调用退出为止。对于许多应用程序来讲,这个主线程是应用程序需要的唯一线程。不过,进程能够创建更多的线程来帮助执行他们的操作。

每个线程都必须有一个进入点函数,线程从这个进入点开始运行。即main、wmain、Win Main或者wWin Main。如果需要在程序中创建辅助线程,它也必定是一个类似如下的进入点函数:

DWORD WINAPI ThreadFunc(PVOID pvParam)
{
    DWORD dwResult = 0;
    ......
    return (dwResult);
}

线程函数可以执行你想它执行的任何任务,最终线程函数到达结尾并且返回。这时,线程终止,该堆栈内存对释放。同时,线程的内核对象的使用计数被递减。

#include <Windows.h>
#include <iostream>
using namespace std;

DWORD WINAPI Fun1(LPVOID lpParameter);

DWORD WINAPI Fun2(LPVOID lpParameter);


int index = 0;
int tickets = 100;   //全局变量tickets用来表示销售的剩余票数
int main()
{
    HANDLE hThread1;
    HANDLE hThread2;
    //创建线程
    hThread1 = CreateThread(NULL, 0, Fun1, NULL, 0, NULL);
    //4个参数的意思分别为:使线程使用默认的安全性、让新线程采用与调用线程一样的栈大小、指定线程的入口函数地址、
    //线程创建标记,0表示让线程一旦创立就运行、新线程的ID,不需要的话为null
    hThread2 = CreateThread(NULL, 0, Fun2, NULL, 0, NULL);
    CloseHandle(hThread1);  //调用CloseHandle将此线程的句柄关闭,关闭句柄时,系统会递减该线程内核对象的使用计数。
    CloseHandle(hThread2);
    Sleep(4000); //让线程暂停运行4s
    system("pause");
    return 0;
}

//线程1入口函数
DWORD WINAPI Fun1(LPVOID lpParameter)
{
    while (TRUE)
    {
        if (tickets > 0)
        {
            Sleep(1);
            cout << "thread1 sell ticket : " << tickets-- << endl;
        }
        else
        {
            break;
        }
    }
    return 0;
}

//线程2的入口函数
DWORD WINAPI Fun2(LPVOID lpParameter)
{
    while (TRUE)
    {
        if (tickets > 0)
        {
            Sleep(1);
            cout << "thread2 sell ticket : " << tickets-- << endl;
        }
        else
        {
            break;
        }
    }
    return 0;
}

结果:和想象的不太一样,为什么会抢着卖票?

参考资料:
http://www.xuebuyuan.com/1470533.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值