C++的线程是如何终止

qin123q 2014-04-13 08:57:50
C++创建了一个线程,在另一个线程如何禁止该线程。
我的功能是:在一个线程PALYPOC的功能是相当于一个播放的功能的,就是将五子棋的数据一个一个读出来,然后显示在棋盘上,相当于回顾一样。(一次播放可以会执行5.6分钟左右)

但是如果我不在想回顾了,我点击重新游戏的时候,我想终止这个线程怎么办。

1 网上说,正常返回,等函数正常返回,就要把这个回顾全部放完才返回,我黄花菜都凉了。

2 还有用什么TerminateProcess的,这个是不建议用的,不会释放占用内存,我用这个函数以后,下次在打开这个文件就打不开了。

3 还有说用个信号量或者表示符的,让我在线程里面做死循环,这个有问题的,(1)这个就意味这,要结束这次循环后才能退出,但是实事上,我只执行一次而已。 (2)我那代码很多的,我怎么用死循环搞啊

还有没有更好的办法,麻烦有办法的就说一下吧,不要说某某书籍有,哪个哪个视频有,直接说一下不行么,你说个视频,说个书籍,我回头还得自己找,还得重新看,你说一下就几分钟的事,这么折腾一点意义都没有。

下面是我的那个线程的方法,可以不看,有兴趣的可以看看能不能用循环搞出来。

//播放线程
DWORD WINAPI PlayProc(LPVOID lpParameter)
{
DATA_PALY *playData=(DATA_PALY *)lpParameter;
CFIVE_CHESSDlg *p=(CFIVE_CHESSDlg*)AfxGetMainWnd();
CFile file(playData->Filename,CFile::modeRead);
CArchive textfile(&file,CArchive::load);
CString data;
textfile>>data;
SplitStr dataArray;
dataArray.SetSplitFlag("+");
dataArray.SetSequenceAsOne(true);
dataArray.SetData(data);
dataArray.GetSplitStrArray(p->n_SaveData_Step);
int Count=p->n_SaveData_Step.GetSize();
for (int i=0;i<Count-1;i++)
{
SplitStr temp;
CStringArray stepData;
temp.SetSplitFlag(",");
temp.SetSequenceAsOne(true);
temp.SetData(p->n_SaveData_Step[i]);
temp.GetSplitStrArray(stepData);
int x=atoi(stepData[0]);
int y=atoi(stepData[1]);
int color=atoi(stepData[2]);
int step=atoi(stepData[3]);
CPoint point(x,y);
p->P_DrawChess(point,color);
Sleep(playData->speed);
CSound sound;
sound.PlayMusic(F_MUSIC_PUTCHESS,1);
CString Step;
Step.Format("第 %d 手",step+1);
p->GetDlgItem(IDC_STEP)->SetWindowText(Step);
}
if (p->n_SaveData_Step[Count-1]=="BLACK")
{
AfxMessageBox("本轮黑棋获胜");
}
else
{
AfxMessageBox("本轮白棋获胜");
}
p->GetDlgItem(IDC_TIPS)->EnableWindow(FALSE);
return 0;
}
...全文
964 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
kuankuan_qiao 2014-04-17
  • 打赏
  • 举报
回复
引用 1 楼 qin123q 的回复:
草泥马的,我刚发问题出来,我就知道怎么做了, 直接在 for那里 做个判断就行了
xiaohutushen30 2014-04-17
  • 打赏
  • 举报
回复
引用 8 楼 BeanJoy 的回复:
Sleep(playData->speed)后,需要等待大致playData->speed这么长时间该线程才会被唤醒,你才有机会处理Sleep下一句。 [code=c] for() { ... DWORD dwStart = ::GetTickCount(); while(::GetTickCount() - dwStart < playData->speed) { if (bStop) { break; } Sleep(1); } if (bStop) { 释放资源等操作; return 0; } ... }
不好意思,前面写的有点问题 tmp=playData->speed; while(tmp--){ sleep(1); if (bStop==true) 退出线程; } 把大的事件分成很多小的事件,中间不断地检查是不是点击了退出
BeanJoy 2014-04-17
  • 打赏
  • 举报
回复
引用 9 楼 xiaohutushen30 的回复:
[quote=引用 8 楼 BeanJoy 的回复:] Sleep(playData->speed)后,需要等待大致playData->speed这么长时间该线程才会被唤醒,你才有机会处理Sleep下一句。 [code=c] for() { ... DWORD dwStart = ::GetTickCount(); while(::GetTickCount() - dwStart < playData->speed) { if (bStop) { break; } Sleep(1); } if (bStop) { 释放资源等操作; return 0; } ... }
不好意思,前面写的有点问题 tmp=playData->speed; while(tmp--){ sleep(1); if (bStop==true) 退出线程; } 把大的事件分成很多小的事件,中间不断地检查是不是点击了退出[/quote] 你这个还是有问题。 你知道tmp--要花多长时间?1毫秒可能,一秒也可能,这么写大大的错误,还是参考参考8楼吧。 或者用事件的方法,Wait时设置一个超时时间。
BeanJoy 2014-04-16
  • 打赏
  • 举报
回复
引用 7 楼 xiaohutushen30 的回复:
[quote=引用 4 楼 BeanJoy 的回复:] [quote=引用 3 楼 xiaohutushen30 的回复:] 看了一下你的代码,也没有你想的那么简单,你代码里面有一个延时,如果线程刚好进入到延时函数,那么就算你终止了线程,线程还是会卡上一会,等延时执行完了才会推出。
这个问题还不好解决吗。

for()
{
    ...
    while(等待时间大于等于playData->speed)
    {
        if (线程该退出了)
        {
            break;
        }
        Sleep(1);
    }
    ...
}
[/quote] 你的意思是另外启动一个线程监控, 请问你的等待时间怎么计算,是正常的每一个循环所用的时间吗?感觉你这段代码没有用,还是一样要等待playData->speed长的时间才能退出。 不过你的这种方式倒是提醒了我快速终止线程的方法,那就是把时间分成很小的时间段,结合楼上的具体实现如下: tmp=playData->speed; while(tmp){ if (bStop==true) 退出线程; } 所以你的那段代码就不用了。 [/quote] Sleep(playData->speed)后,需要等待大致playData->speed这么长时间该线程才会被唤醒,你才有机会处理Sleep下一句。

for()
{
    ...
    DWORD dwStart = ::GetTickCount();
    while(::GetTickCount() - dwStart < playData->speed)
    {
        if (bStop)
        {
            break;
        }
        Sleep(1);
    }
    if (bStop)
    {
        释放资源等操作;
        return 0;
    }
    ...
}
xiaohutushen30 2014-04-16
  • 打赏
  • 举报
回复
引用 4 楼 BeanJoy 的回复:
[quote=引用 3 楼 xiaohutushen30 的回复:] 看了一下你的代码,也没有你想的那么简单,你代码里面有一个延时,如果线程刚好进入到延时函数,那么就算你终止了线程,线程还是会卡上一会,等延时执行完了才会推出。
这个问题还不好解决吗。

for()
{
    ...
    while(等待时间大于等于playData->speed)
    {
        if (线程该退出了)
        {
            break;
        }
        Sleep(1);
    }
    ...
}
[/quote] 你的意思是另外启动一个线程监控, 请问你的等待时间怎么计算,是正常的每一个循环所用的时间吗?感觉你这段代码没有用,还是一样要等待playData->speed长的时间才能退出。 不过你的这种方式倒是提醒了我快速终止线程的方法,那就是把时间分成很小的时间段,结合楼上的具体实现如下: tmp=playData->speed; while(tmp){ if (bStop==true) 退出线程; } 所以你的那段代码就不用了。
BeanJoy 2014-04-14
  • 打赏
  • 举报
回复
引用 3 楼 xiaohutushen30 的回复:
看了一下你的代码,也没有你想的那么简单,你代码里面有一个延时,如果线程刚好进入到延时函数,那么就算你终止了线程,线程还是会卡上一会,等延时执行完了才会推出。
这个问题还不好解决吗。

for()
{
    ...
    while(等待时间大于等于playData->speed)
    {
        if (线程该退出了)
        {
            break;
        }
        Sleep(1);
    }
    ...
}
worldy 2014-04-14
  • 打赏
  • 举报
回复
for循环中设置一个标志,如果标志被设置,则退出 for (int i=0;i<Count-1;i++) { if(bStop) break;//bStop为一全局变量,你可以在界面上使用一个按键设置 SplitStr temp; CStringArray stepData; temp.SetSplitFlag(","); temp.SetSequenceAsOne(true); temp.SetData(p->n_SaveData_Step[i]); temp.GetSplitStrArray(stepData); int x=atoi(stepData[0]); int y=atoi(stepData[1]); int color=atoi(stepData[2]); int step=atoi(stepData[3]); CPoint point(x,y); p->P_DrawChess(point,color); Sleep(playData->speed); CSound sound; sound.PlayMusic(F_MUSIC_PUTCHESS,1); CString Step; Step.Format("第 %d 手",step+1); p->GetDlgItem(IDC_STEP)->SetWindowText(Step); }
worldy 2014-04-14
  • 打赏
  • 举报
回复
for循环中设置一个标志,如果标志被设置,则退出 for (int i=0;i<Count-1;i++) { if(bStop) break;//bStop为一全局变量,你可以在界面上使用一个按键设置 SplitStr temp; CStringArray stepData; temp.SetSplitFlag(","); temp.SetSequenceAsOne(true); temp.SetData(p->n_SaveData_Step[i]); temp.GetSplitStrArray(stepData); int x=atoi(stepData[0]); int y=atoi(stepData[1]); int color=atoi(stepData[2]); int step=atoi(stepData[3]); CPoint point(x,y); p->P_DrawChess(point,color); Sleep(playData->speed); CSound sound; sound.PlayMusic(F_MUSIC_PUTCHESS,1); CString Step; Step.Format("第 %d 手",step+1); p->GetDlgItem(IDC_STEP)->SetWindowText(Step); }
xiaohutushen30 2014-04-13
  • 打赏
  • 举报
回复
看了一下你的代码,也没有你想的那么简单,你代码里面有一个延时,如果线程刚好进入到延时函数,那么就算你终止了线程,线程还是会卡上一会,等延时执行完了才会推出。
BeanJoy 2014-04-13
  • 打赏
  • 举报
回复
for里面检测一个变量不行吗? 想停止回放时,设置这个变量的值,for中检测到了就退出。
qin123q 2014-04-13
  • 打赏
  • 举报
回复
草泥马的,我刚发问题出来,我就知道怎么做了, 直接在 for那里 做个判断就行了

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧