weileshenghuo1 2014-08-30 09:55 采纳率: 0%
浏览 1012

孙鑫视频第15章,多线程的创建,用互斥机制模拟火车票售票,我的问题,望大神指点

问题:当我设的总票数超过298时(比如500,1000),我的票都是从第298张开始卖的,正常的应该是总票数是多少张,就是从多少张开始卖的吧,当总票数小于298时,就是正常卖票,下面是我的代码,和运行结果的图片(当票数为500时),我的编译环境是vs 2008请大神指点
#include
#include
using namespace std;
DWORD WINAPI ThreadFun1(
In LPVOID lpParameter
);
DWORD WINAPI ThreadFun2(
In LPVOID lpParameter
);
static UINT tickets=500;
HANDLE hMutex;

void main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1=CreateThread(NULL,0,ThreadFun1,NULL, 0,NULL);
hThread2=CreateThread(NULL,0,ThreadFun2,NULL, 0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
/*while(index++<1000)
cout<<"Main Thread is running\n";*/
hMutex=CreateMutex(NULL,FALSE,NULL);
Sleep(4000);
//Sleep(10);
}
DWORD WINAPI ThreadFun1(
In LPVOID lpParameter
)
{
/*while(index++<1000)
cout<<"Thread1 is running\n";*/

while(TRUE)
{
    WaitForSingleObject(hMutex,INFINITE);
    if(tickets>0)
    {
        cout<<"Thread1:"<<tickets--<<'\n';
        /*puts("Thread1:");
        printf("%d",tickets);
        tickets--;*/ 
    }
    else
        break;
    ReleaseMutex(hMutex);
}

return 0;

}
DWORD WINAPI ThreadFun2(
In LPVOID lpParameter
)
{
/*while(index++<1000)
cout<<"Thread1 is running\n";*/

while(TRUE)
{
    WaitForSingleObject(hMutex,INFINITE);
    if(tickets>0)
        cout<<"Thread2:"<<tickets--<<'\n';
    /*{
    puts("Thread2:");
    printf("%d",tickets);
    tickets--;
    }*/
    else
        break;
    ReleaseMutex(hMutex);
}

return 0;

}
控制台运行结果最顶端部分:
CSDN移动问答
控制台运行最下面部分:
CSDN移动问答

  • 写回答

1条回答

  • ChatGPTᴼᴾᴱᴺᴬᴵ 2023-03-24 20:08
    关注

    该回答引用ChatGPT-3.5

    根据你的代码,问题可能出现在互斥体的使用上。在线程中使用互斥体可以确保多个线程不会同时修改共享资源,但是在你的代码中,互斥体的使用并不完整。在每个线程的 while 循环中,只有取走票时才释放互斥体,但是如果票数已经为 0,while 循环就会直接跳出,没有机会释放互斥体。这就会导致后续线程获取不到互斥体,无法修改票数。


    正确的做法是将 WaitForSingleObject 和 ReleaseMutex 包含在 while 循环中,并在循环结束时释放互斥体。这样可以确保每个线程都能正确获取和释放互斥体,保证票数的正确性。修改后的代码如下:

    #include <iostream>
    #include <windows.h>
    
    using namespace std;
    
    DWORD WINAPI ThreadFun1(LPVOID lpParameter);
    DWORD WINAPI ThreadFun2(LPVOID lpParameter);
    
    static UINT tickets = 500;
    HANDLE hMutex;
    
    int main() {
        HANDLE hThread1;
        HANDLE hThread2;
    
        hThread1 = CreateThread(NULL, 0, ThreadFun1, NULL, 0, NULL);
        hThread2 = CreateThread(NULL, 0, ThreadFun2, NULL, 0, NULL);
    
        CloseHandle(hThread1);
        CloseHandle(hThread2);
    
        hMutex = CreateMutex(NULL, FALSE, NULL);
    
        Sleep(4000);
        return 0;
    }
    
    DWORD WINAPI ThreadFun1(LPVOID lpParameter) {
        while (TRUE) {
            WaitForSingleObject(hMutex, INFINITE);
    
            if (tickets > 0) {
                cout << "Thread1: " << tickets-- << endl;
            } else {
                break;
            }
    
            ReleaseMutex(hMutex);
        }
    
        ReleaseMutex(hMutex);
        return 0;
    }
    
    DWORD WINAPI ThreadFun2(LPVOID lpParameter) {
        while (TRUE) {
            WaitForSingleObject(hMutex, INFINITE);
    
            if (tickets > 0) {
                cout << "Thread2: " << tickets-- << endl;
            } else {
                break;
            }
    
            ReleaseMutex(hMutex);
        }
    
        ReleaseMutex(hMutex);
        return 0;
    }
    

    此外,你提到的问题也可能与你的环境有关。如果你在 VS 2008 环境下编译代码,需要确保正确设置了编译器选项和链接选项,以确保生成的可执行文件可以在当前操作系统上正确运行。

    评论

报告相同问题?

悬赏问题

  • ¥15 flink cdc无法实时同步mysql数据
  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名