//定时答题程序,从文件中读入题号和答案,开两个线程FunProc1(定时用的)、FunProc2(输入答案用的),
//如果时间到了但还没答题则直接进入下一题,并重新计时;如果在规定时间内答完题,则也直接进入下一题,并重新计时。
//问题就是:a.时间到了还没答题的情况下,进入了下一题后,无法输入。不知道哪儿出错了……
//     b.这里要不用TerminateThread而让另一个线程结束,该怎么改?大虾们,谢谢了!
//D:\\Question.txt
//1 C
//2 B
//3 A
//4 D
//5 B
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <fstream>
#include <map>
using namespace std;
bool g_time;
bool g_input; 
HANDLE hThread1;
HANDLE hThread2;
DWORD WINAPI FunProc1(
  LPVOID lpParameter
)
{
Sleep(*(DWORD*)lpParameter);
cout<<"Sorry,time over!"<<endl;
TerminateThread(hThread2,0); //如果时间到还没有输入答案的话,就结束线程hThread2
g_time=true;
return 0;
}
DWORD WINAPI FunProc2(
LPVOID lpParameter
)
{
pair<int,char> icpair(*(pair<int,char>*)lpParameter);
cout<<"Time is running !Please input the answer of question "<<icpair.first<<":"<<endl;
char a;
cin>>a;
g_input=true;
TerminateThread(hThread1,0); //输入答案后立即结束定时线程hThread1
if(a==icpair.second)
cout<<"Right"<<endl;
else
cout<<"Wrong"<<endl;
return 0;
}
int main()
{
ifstream ifile("D:\\Question.txt");
if(!ifile)
{
cerr<<"Can't find the ifile!"<<ifile<<endl;
return 1;
}
map<int,char> icmap;
int index;
char answer;
while(ifile>>index>>answer) //从文件中得到题号和答案
icmap[index]=answer;
ifile.close(); g_time=false;
g_input=false;
int t=3000; //定时3秒
int *time=&t;
for(map<int,char>::iterator iter=icmap.begin();iter!=icmap.end();++iter)
{
hThread1=CreateThread(NULL,0,FunProc1,(LPVOID)time,0,NULL);
hThread2=CreateThread(NULL,0,FunProc2,(LPVOID)(&(*iter)),0,NULL);
while(!g_time&&!g_input)
{
Sleep(100);
}
g_time=false;
g_input=false;
CloseHandle(hThread1);
CloseHandle(hThread2);
}
return 0;
}

解决方案 »

  1.   

    1.第一个问题:g_input=true;应该放在后面。因为如果设置了TRUE,则主函数中就会运行CloseHandle(hThread2);导致下面的答案判断部分可能无法。        TerminateThread(hThread1,0);        //输入答案后立即结束定时线程hThread1
        if(a==icpair.second)
            cout<<"Right"<<endl;
        else
            cout<<"Wrong"<<endl;
    g_input=true;2.g_input、g_time都是共享数据,写时要使用保护。最好将这些变量的写及TerminateThread操作都保护起来。
    主函数的最后四行代码也应该保护起来。保护的方法:
    static inline void InitCacheMutext() {
        if (!cacheMutexInitialized) {
            InitializeCriticalSection(&cacheMutex);
            cacheMutexInitialized = 1;
        }
    }
    void LockCache(void) {
        InitCacheMutext();
        EnterCriticalSection(&cacheMutex);
    }
    void UnlockCache(void) {
        LeaveCriticalSection(&cacheMutex);
    }
      

  2.   

    g_input=true;应该放在后面
    我放后面了,还是无法输入……线程不懂,翔哥帮忙!谢谢……