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

时间:2020-12-08 21:13:18
问题:我设的总票数超过298时(比如500,1000),我的票都是从第298张开始卖的,当总票数小于298时,就是正常的买票,下面是我的代码,和运行结果的图片(当票数为500时),我的编译环境是vs 2008请大神指点
#include <iostream>
#include <Windows.h>
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;
}
控制台结果图片:
控制台上半部分
孙鑫视频第15章,多线程的创建,用互斥机制模拟火车票售票,我的问题,望大神指点
控制台的最下面部分:
孙鑫视频第15章,多线程的创建,用互斥机制模拟火车票售票,我的问题,望大神指点

8 个解决方案

#1


那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前。另外线程函数中else部分在break之前需要调用ReleaseMutex()

#2


楼上,您好,我刚才按照您说的试了一下,不过结果还是跟我之前运行的结果一样,我想有没有可能是控制台的问题,它实际上是从500张开始卖的,但是没有显示出来,有没有这种可能,还有这个结果有没有可能跟我的电脑的cpu双核有关系呀

#3


引用 2 楼 weileshenghuo1 的回复:
楼上,您好,我刚才按照您说的试了一下,不过结果还是跟我之前运行的结果一样,我想有没有可能是控制台的问题,它实际上是从500张开始卖的,但是没有显示出来,有没有这种可能,还有这个结果有没有可能跟我的电脑的cpu双核有关系呀


rebuild all

不应该是从298开始,

500 开始才对。

#4


前面的被覆盖了吧。。。。。

你可以试着用一个for循环,用500输出到0试试。

#5


引用 1 楼 VisualEleven 的回复:
那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前。另外线程函数中else部分在break之前需要调用ReleaseMutex()


那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前

这里根本没有问题

只是不符合一般习惯,确实有些别扭。

程序最大的问题是: releasemutex的问题,当然你也说,


所以楼主的代码目前没有问题。

之所以出现那个奇怪的问题: ,从298开始,

是控制台的显示导致的, 控制台显示不完全,所以误以为有问题。

楼主,可以把cout, pritnf的结果保存到 文件里。

查看

#6


引用 5 楼 u012879787 的回复:
Quote: 引用 1 楼 VisualEleven 的回复:

那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前。另外线程函数中else部分在break之前需要调用ReleaseMutex()


那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前

这里根本没有问题

只是不符合一般习惯,确实有些别扭。

程序最大的问题是: releasemutex的问题,当然你也说,


所以楼主的代码目前没有问题。

之所以出现那个奇怪的问题: ,从298开始,

是控制台的显示导致的, 控制台显示不完全,所以误以为有问题。

楼主,可以把cout, pritnf的结果保存到 文件里。

查看



更正一下,createmutex确实有问题。

楼主可以想想, 线程函数开执行后, watiforsinge等待这个互斥体是否有信号或者被触发。

开始这个互斥体,压根没创建,是个无效的句柄。

所以是有问题的。

#7


引用 5 楼 u012879787 的回复:
之所以出现那个奇怪的问题: ,从298开始,

是控制台的显示导致的, 控制台显示不完全,所以误以为有问题。

就是是控制台显示的问题,楼主你改成每卖几张票换一次行就可以显示完整了。

#define numPerLine 5
//......
cout<<"Thread1:"<<tickets-- << ' ';
if(tickets % numPerLine == 0)
{
cout << endl;
}
.//......

#8


感谢大家了,我找到原因了,我刚才试了一下4楼的,我的循环是从0到499,但控制台显示的最上端是202,最下端是499,也就是说也是只显示了298行,而且我也试了一下7楼的,这次最上端是271张票,但是因为输出了空行,我数了下,中间是27个空行,也就是说还是298行,最后我试了下5楼,最后觉得应该就是控制台的问题,因为,我设置的票数是1000,然后输到了txt文件里,文件里显示的是从1000张开始卖的,所以感谢大家了,是控制台的问题,它只能显示298行

#1


那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前。另外线程函数中else部分在break之前需要调用ReleaseMutex()

#2


楼上,您好,我刚才按照您说的试了一下,不过结果还是跟我之前运行的结果一样,我想有没有可能是控制台的问题,它实际上是从500张开始卖的,但是没有显示出来,有没有这种可能,还有这个结果有没有可能跟我的电脑的cpu双核有关系呀

#3


引用 2 楼 weileshenghuo1 的回复:
楼上,您好,我刚才按照您说的试了一下,不过结果还是跟我之前运行的结果一样,我想有没有可能是控制台的问题,它实际上是从500张开始卖的,但是没有显示出来,有没有这种可能,还有这个结果有没有可能跟我的电脑的cpu双核有关系呀


rebuild all

不应该是从298开始,

500 开始才对。

#4


前面的被覆盖了吧。。。。。

你可以试着用一个for循环,用500输出到0试试。

#5


引用 1 楼 VisualEleven 的回复:
那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前。另外线程函数中else部分在break之前需要调用ReleaseMutex()


那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前

这里根本没有问题

只是不符合一般习惯,确实有些别扭。

程序最大的问题是: releasemutex的问题,当然你也说,


所以楼主的代码目前没有问题。

之所以出现那个奇怪的问题: ,从298开始,

是控制台的显示导致的, 控制台显示不完全,所以误以为有问题。

楼主,可以把cout, pritnf的结果保存到 文件里。

查看

#6


引用 5 楼 u012879787 的回复:
Quote: 引用 1 楼 VisualEleven 的回复:

那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前。另外线程函数中else部分在break之前需要调用ReleaseMutex()


那个代码是有问题的,hMutex=CreateMutex(NULL,FALSE,NULL);放到CreateThread创建线程之前

这里根本没有问题

只是不符合一般习惯,确实有些别扭。

程序最大的问题是: releasemutex的问题,当然你也说,


所以楼主的代码目前没有问题。

之所以出现那个奇怪的问题: ,从298开始,

是控制台的显示导致的, 控制台显示不完全,所以误以为有问题。

楼主,可以把cout, pritnf的结果保存到 文件里。

查看



更正一下,createmutex确实有问题。

楼主可以想想, 线程函数开执行后, watiforsinge等待这个互斥体是否有信号或者被触发。

开始这个互斥体,压根没创建,是个无效的句柄。

所以是有问题的。

#7


引用 5 楼 u012879787 的回复:
之所以出现那个奇怪的问题: ,从298开始,

是控制台的显示导致的, 控制台显示不完全,所以误以为有问题。

就是是控制台显示的问题,楼主你改成每卖几张票换一次行就可以显示完整了。

#define numPerLine 5
//......
cout<<"Thread1:"<<tickets-- << ' ';
if(tickets % numPerLine == 0)
{
cout << endl;
}
.//......

#8


感谢大家了,我找到原因了,我刚才试了一下4楼的,我的循环是从0到499,但控制台显示的最上端是202,最下端是499,也就是说也是只显示了298行,而且我也试了一下7楼的,这次最上端是271张票,但是因为输出了空行,我数了下,中间是27个空行,也就是说还是298行,最后我试了下5楼,最后觉得应该就是控制台的问题,因为,我设置的票数是1000,然后输到了txt文件里,文件里显示的是从1000张开始卖的,所以感谢大家了,是控制台的问题,它只能显示298行