信阳毛尖 本版等级: 结帖率:100% | 楼主发表于: 2011-04-11 21:05:47 要实现的功能就像360扫描一样,单击“开始”按钮,开始执行,此时按钮的Caption改变为“暂停”,再次单击这个按钮,程序接着上次暂停的地方继续执行。在我的程序中,OnBnClicked函数中,由于程序的需要,是创建一个线程,程序功能在线程函数中实现。线程函数主要部分是通过网卡循环向局域网各个主机发送报文并接收它们的响应报文进行相应的处理,其中又用到很多自定义的函数模块。 C/C++ code ?
没有思绪了,貌似要用到信号量: 申请一个信号量: hEvent=::CreateEvent(NULL,TURE,TURE,lpName);//第二个参数是TURE,设定为手动模式,防止::WaitForSingleObject改变信号量的状态。 在所有线程可以被暂停的地方加上: ::WaitForSingleObject(hEvent,-1); 这样,只需要用这两个函数 ::SetEvent(hEvent);//继续 ::ResetEvent(hEvent);//暂停 疑问一:如果用信号量的话,我这个程序改怎么改?“暂停”、“继续”函数具体加在什么地方?(如果这么用,我觉得线程中的循环可能会出问题,欢迎大家讨论一下) 疑问二:用SuspendThread 挂起(暂停)线程、ResumeThread 继续执行线程函数是否会好一些? 疑问三:程序逻辑上肯定存在问题,程序刚启动按钮自然是“扫描”状态,第一次单击逻辑没有问题,创建线程执行;第二次单击,暂停线程,逻辑也没有问题,当第三次单击时,逻辑就有问题了:应该是继续执行线程,而不是再次创建线程。 改成这样: C/C++ code ?
好像逻辑也不对!!! 初次接触这个东西,望大家指教!! 更多0分享到: | ||||
回复次数:30 |
疯狂-的-蜗牛 本版等级: | #1 得分:5回复于: 2011-04-11 21:07:37 顶一下,你比我强多了,我不知道呵呵、 |
智能卡_Snooper 本版等级: | #2 得分:5回复于: 2011-04-11 21:18:17 开始、暂停、继续 用一个变量就行了 |
秦剑 本版等级: | #4 得分:5回复于: 2011-04-11 21:20:40 SuspendThread(m_hHandle); |
Devil26 本版等级: | #5 得分:5回复于: 2011-04-11 21:23:29 创建一个BOOL变量表明是否需要创建线程,如果第一次当然创建,之后点击就不用创建了,不知道对不对哦 |
智能卡_Snooper 本版等级: | #6 得分:10回复于: 2011-04-11 21:24:49 C/C++ code ?
| ||
Eleven 本版等级: | #7 得分:30回复于: 2011-04-11 21:25:37 疑问一: CreateSemphore/ReleaseSemaphore,和EVENT的处理差不多的,SetEvent/ReSetEvent()疑问二:不建议使用SuspendThread/ResumeThread();因为SuspendThread和ResumeThread的作用其实很简单,他们都是通过线程的HANDLE到线程的数据结构中将一个计数的变量做加一减一的操作, 如果线程在运行时监测到线程的Suspend Count计数大于0,那么线程就会暂停处理任何消息和循环的进行,这时CPU将不为该线程分配时间片,如果线程的Suspend Count小于等于0,线程将正常运行。所以ResumeThread的一次调用并不一定导致线程的运行,SuspendThread也不一定导致线程挂起,关键在于线程的挂起计数。 疑问三:判断一下是否存在 C/C++ code ?
| ||
秦剑 本版等级: | #8 得分:5回复于: 2011-04-11 21:27:12 DWORD WINAPI SuspendThread( |
Dreadnought 本版等级: | #9 得分:5回复于: 2011-04-11 21:31:40 创建个BOOL型的变量用来判断 |
King_hhuang 本版等级:
| #10 得分:20回复于: 2011-04-11 21:32:51 程序"开始"时创建线程,你需要执行的操作放到线程中的while循环中,循环中每次判断WaitForSingleObject(_hEvent, INFINITE);如果需要"继续",SetEvent(_hEvent); 需要"暂停",ResetEvent(_hEvent); 看看这个程序,不知道让你对Event的用法有些启发: C/C++ code ?
| ||
走走刀口 本版等级: | #11 得分:5回复于: 2011-04-11 21:38:11 使用PV操作 |
写不动代码的人 本版等级:
| #12 得分:5回复于: 2011-04-11 22:00:35 hEvent=::CreateEvent(NULL,TURE,TURE,lpName);//第二个参数是TURE,设定为手动模式,防止::WaitForSingleObject改变信号量的状态。 |
samako 本版等级: | #13 得分:5回复于: 2011-04-11 23:24:57 路过的,看下 |
wmnmtm 本版等级: | #14 得分:5回复于: 2011-04-11 23:58:24 线程应该不退出,只是判断那个全局变量,如果处于暂停,那么就忽略对应的执行代码吧。 |
hztj2005 本版等级: | #15 得分:20回复于: 2011-04-12 00:25:38 没有多难吧 |
b245930557 本版等级: | #16 得分:5回复于: 2011-04-12 00:49:49 无论你是使用临界区对象、互锁函数、事件内核对象、信号量内核对象还是互斥内核对象,原理都差不多,也很简单 |
xiaopoy 本版等级: | #17 得分:5回复于: 2011-04-12 01:00:04 在循环的函数里是否继续处理下一个的地方加上对信号量的判断不就可以了? |
xiaopoy 本版等级: | #18 得分:5回复于: 2011-04-12 01:18:14 我刚在没看内容瞎说话: |
无水先生 本版等级: | #20 得分:5回复于: 2011-04-12 07:00:29 思路: |
jyh_baoding 本版等级: | #21 得分:5回复于: 2011-04-12 08:15:29 都是自己定义的逻辑控制,记录当前状态就可以了,知道当前的什么状态就好操作了 |
qiuxin425 本版等级: | #22 得分:4回复于: 2011-04-12 09:16:29 设置一个BOOL变量,为真给线程发操作事件,为假不发,用timer时钟来发 |
向立天 本版等级: | #23 得分:30回复于: 2011-04-12 09:51:45 小兄弟 |
信阳毛尖 本版等级: | #24 得分:0回复于: 2011-04-12 11:14:23 引用 23 楼 xianglitian 的回复:小兄弟 感激不尽!!!! 有劳大哥发一下: 569051911@qq.com |
信阳毛尖 本版等级: | #25 得分:0回复于: 2011-04-12 11:17:10 顺便问一下: |
向立天 本版等级: | #26 得分:0回复于: 2011-04-12 11:42:12 我发了 |
King_hhuang 本版等级:
| #27 得分:5回复于: 2011-04-12 11:45:05 引用 25 楼 lsq19871207 的回复:顺便问一下: 放在你的业务操作开始前 |
忽悠 本版等级: | #28 得分:3回复于: 2011-04-12 11:46:12 我是新手说下我的方法,我做的是批量文件转换,定义BOOL类型的变量 m_bRun,初始化index为0,index为文件个数,这样控制m_bRun的值可以实现暂停和继续功能 |
smwhotjay 本版等级: | #29 得分:3回复于: 2011-04-12 12:08:39 Event,很好. 我就用Event写了个线程池. |
信阳毛尖 本版等级: | #30 得分:0回复于: 2011-04-12 14:06:54 万事开头难,经过大家的指导,这个功能已经实现,先谢谢大家!现总结一下: 创建线程函数ScanEthernet 1、在线程创建的时候申请信号量,如我的程序: C/C++ code ?
2、根据程序的需要,在线程处理函数中添加WaitForSingleObject(g_hEvent, INFINITE)函数,在我的程序中,是在for循环中开始位置添加的 ,因为这个发送数据包循环是线程处理函数的主体部分,程序运行起来后除了初始化,就是通过这个循环来实现其功能,因此,加在循环外自然是不合理的 3、在单击按钮处理函数中,根据自身程序的需要,添加 ::ResetEvent(g_hEvent);//暂停 和 ::SetEvent(g_hEvent);//继续 注意: CreateEvent(NULL,TRUE,FALSE,NULL)函数的第二个参数一定要设置为TRUE,即手动模式,防止::WaitForSingleObject改变信号量的状态,一开始我就把其设置为FALSE,结果是单击按钮时,只循环执行一次,而且会出现“继续”与“暂停”执行效果相反的情况,这就是WaitForSingleObject本身改变信号量的状态 所造成的 |