《WINDOWS核心编程》中说可以使用
DWORD SuspendThread ( HANDLE hThread ); //挂起线程
DWORD ResumeThread ( HANDLE hThread ); //恢复线程
是不是使用这两个函数就行?
比如我在int main()中创建了两个线程
handle[0]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,NULL,0,NULL);
handle[1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc2,NULL,0,NULL);
线程函数ThreadFunc1执行一个任务操作(比如循环写入0至9),而ThreadFunc2不断检测某个条件的是否满足,如果满足,则暂停线程1的任务操作,是不是这样写就行:
ThreadFunc2()
{
if(条件满足)
{
SuspendThread(handle[0]);
//报警声;
}
}
10 个解决方案
#1
是不是?自己试试不就知道了吗 总共就2个API 有问的功夫早就试出来了
#2
对啊
你把它加入代码里面
如果参数没问题的画
逻辑上是可以通过的
你把它加入代码里面
如果参数没问题的画
逻辑上是可以通过的
#3
函数是对的。
你在ThreadFunc2中Suspend,得先确保thread1的线程函数这时候还没有退出。
你在ThreadFunc2中Suspend,得先确保thread1的线程函数这时候还没有退出。
#4
TO ydfivy
我其实也是这个疑问。那是不是还需要再建立一个同步事件?
我其实也是这个疑问。那是不是还需要再建立一个同步事件?
#5
因为不太明白楼主的用意。所以不能轻易出主意。
如果你想让第一个线程挂起,你可以在创建线程后,就将其挂起。然后在第二个线程中Resume.
用不用同步,这个楼主按照自己的想法来决定吧。:)
如果你想让第一个线程挂起,你可以在创建线程后,就将其挂起。然后在第二个线程中Resume.
用不用同步,这个楼主按照自己的想法来决定吧。:)
#6
To ydfvy:
还是有问题。贴出我的代码,您看一下。按了“执行”后,程序运行起来,然后在记事本B中输入a后,记事本A中循环输入数字暂停,但无法点击“恢复线程1”的按钮,程序无响应,鼠标呈现一直在忙碌的状态...
注:以下代码中的dm1 dm2是个叫“大漠插件”的对象,就是绑定窗口后,可以对窗口内输入字符、找图等。
还是有问题。贴出我的代码,您看一下。按了“执行”后,程序运行起来,然后在记事本B中输入a后,记事本A中循环输入数字暂停,但无法点击“恢复线程1”的按钮,程序无响应,鼠标呈现一直在忙碌的状态...
注:以下代码中的dm1 dm2是个叫“大漠插件”的对象,就是绑定窗口后,可以对窗口内输入字符、找图等。
//第一个线程:向记事本A中不断写入0 1 2 3 4 5 6 7 8 9
unsigned int _stdcall ThreadFunc1(void *pm1)
{
dm1.BindWindow(0x4b068e,"gdi","windows","windows",0);
Sleep(100);
int i=0;
while (true)
{
dm1.KeyPress(48+i%10);
Sleep(1000);
i++;
}
dm1.UnBindWindow();
return 0;
}
//第二个线程:每隔五秒,检测记事本B中是否出现了字母a,若出现了字母a,发出声音,并挂起线程1
unsigned int _stdcall ThreadFunc2(void *pm2)
{
VARIANT intXR,intYR,width,height;
dm2.SetPath("I:\\路径");
//绑定窗口
dm2.BindWindow(0x59063e,"gdi","windows","windows",0);
dm2.GetClientSize(0x59063e,&width,&height);
while(true)
{
Sleep(5000);
long find_rwret=dm2.FindPic(0,0,width.lVal,height.lVal,"a.bmp","020202",1,0,&intXR,&intYR);
if(find_rwret>=0)
{
dm2.Play("allsuccess.wav");
::SuspendThread(handle[0]);
//退出检测
break;
}
}
dm2.UnBindWindow();
return 0;
}
//有两个按钮
//第一个按钮:"执行",开始执行线程1和线程2
void CDxcTestDmDlg::OnButton1()
{
//线程1
handle[0]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,NULL,0,NULL);
//线程2
handle[1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc2,NULL,0,NULL);
WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);
}
//第二个按钮:“恢复线程1”
void CDxcTestDmDlg::OnButton2()
{
ResumeThread(handle[0]);
}
#7
void CDxcTestDmDlg::OnButton1()
{
//线程1
handle[0]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,NULL,0,NULL);
//线程2
handle[1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc2,NULL,0,NULL);
WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);
}
这里的Wait函数在死等,界面线程已经停止响应了。你点不了Button2正常。
{
//线程1
handle[0]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,NULL,0,NULL);
//线程2
handle[1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc2,NULL,0,NULL);
WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);
}
这里的Wait函数在死等,界面线程已经停止响应了。你点不了Button2正常。
#8
WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);这个第三个参数改成FALSE。
这样Thread2退出,你的界面就能响应了。
这样Thread2退出,你的界面就能响应了。
#9
To ydfivy:
太对了,感谢!
不过我又有了一个新的问题。如果把线程函数2中的break注释掉,也就是说发现有字母a时(满足条件时),只是挂起线程1,但线程2仍继续循环检测(因为我可以把记事本B中的a手动删除掉),那么这样的话,线程2就永远退不出来,这样即使WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE)的第三个参数改成FALSE夜不好使了,那该怎么办呢??
太对了,感谢!
不过我又有了一个新的问题。如果把线程函数2中的break注释掉,也就是说发现有字母a时(满足条件时),只是挂起线程1,但线程2仍继续循环检测(因为我可以把记事本B中的a手动删除掉),那么这样的话,线程2就永远退不出来,这样即使WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE)的第三个参数改成FALSE夜不好使了,那该怎么办呢??
//第二个线程:每隔五秒,检测记事本B中是否出现了字母a,若出现了字母a,发出声音,并挂起线程1
unsigned int _stdcall ThreadFunc2(void *pm2)
{
VARIANT intXR,intYR,width,height;
dm2.SetPath("I:\\路径");
//绑定窗口
dm2.BindWindow(0x59063e,"gdi","windows","windows",0);
dm2.GetClientSize(0x59063e,&width,&height);
while(true)
{
Sleep(5000);
long find_rwret=dm2.FindPic(0,0,width.lVal,height.lVal,"a.bmp","020202",1,0,&intXR,&intYR);
if(find_rwret>=0)
{
dm2.Play("allsuccess.wav");
::SuspendThread(handle[0]);
//把break注释掉,也就是说发现有字母a时(满足条件时),只是挂起线程1,但线程2仍继续循环检测(因为我可以把记事本B中的a手动删除掉)
//break;
}
}
dm2.UnBindWindow();
return 0;
}
#10
啊O,好复杂。
呵呵。
办法就是把现在做的这些再移动一个工作线程里。然后根据上边那两个线程的状态,设置按钮是disable还是enable.
呵呵。
办法就是把现在做的这些再移动一个工作线程里。然后根据上边那两个线程的状态,设置按钮是disable还是enable.
#1
是不是?自己试试不就知道了吗 总共就2个API 有问的功夫早就试出来了
#2
对啊
你把它加入代码里面
如果参数没问题的画
逻辑上是可以通过的
你把它加入代码里面
如果参数没问题的画
逻辑上是可以通过的
#3
函数是对的。
你在ThreadFunc2中Suspend,得先确保thread1的线程函数这时候还没有退出。
你在ThreadFunc2中Suspend,得先确保thread1的线程函数这时候还没有退出。
#4
TO ydfivy
我其实也是这个疑问。那是不是还需要再建立一个同步事件?
我其实也是这个疑问。那是不是还需要再建立一个同步事件?
#5
因为不太明白楼主的用意。所以不能轻易出主意。
如果你想让第一个线程挂起,你可以在创建线程后,就将其挂起。然后在第二个线程中Resume.
用不用同步,这个楼主按照自己的想法来决定吧。:)
如果你想让第一个线程挂起,你可以在创建线程后,就将其挂起。然后在第二个线程中Resume.
用不用同步,这个楼主按照自己的想法来决定吧。:)
#6
To ydfvy:
还是有问题。贴出我的代码,您看一下。按了“执行”后,程序运行起来,然后在记事本B中输入a后,记事本A中循环输入数字暂停,但无法点击“恢复线程1”的按钮,程序无响应,鼠标呈现一直在忙碌的状态...
注:以下代码中的dm1 dm2是个叫“大漠插件”的对象,就是绑定窗口后,可以对窗口内输入字符、找图等。
还是有问题。贴出我的代码,您看一下。按了“执行”后,程序运行起来,然后在记事本B中输入a后,记事本A中循环输入数字暂停,但无法点击“恢复线程1”的按钮,程序无响应,鼠标呈现一直在忙碌的状态...
注:以下代码中的dm1 dm2是个叫“大漠插件”的对象,就是绑定窗口后,可以对窗口内输入字符、找图等。
//第一个线程:向记事本A中不断写入0 1 2 3 4 5 6 7 8 9
unsigned int _stdcall ThreadFunc1(void *pm1)
{
dm1.BindWindow(0x4b068e,"gdi","windows","windows",0);
Sleep(100);
int i=0;
while (true)
{
dm1.KeyPress(48+i%10);
Sleep(1000);
i++;
}
dm1.UnBindWindow();
return 0;
}
//第二个线程:每隔五秒,检测记事本B中是否出现了字母a,若出现了字母a,发出声音,并挂起线程1
unsigned int _stdcall ThreadFunc2(void *pm2)
{
VARIANT intXR,intYR,width,height;
dm2.SetPath("I:\\路径");
//绑定窗口
dm2.BindWindow(0x59063e,"gdi","windows","windows",0);
dm2.GetClientSize(0x59063e,&width,&height);
while(true)
{
Sleep(5000);
long find_rwret=dm2.FindPic(0,0,width.lVal,height.lVal,"a.bmp","020202",1,0,&intXR,&intYR);
if(find_rwret>=0)
{
dm2.Play("allsuccess.wav");
::SuspendThread(handle[0]);
//退出检测
break;
}
}
dm2.UnBindWindow();
return 0;
}
//有两个按钮
//第一个按钮:"执行",开始执行线程1和线程2
void CDxcTestDmDlg::OnButton1()
{
//线程1
handle[0]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,NULL,0,NULL);
//线程2
handle[1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc2,NULL,0,NULL);
WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);
}
//第二个按钮:“恢复线程1”
void CDxcTestDmDlg::OnButton2()
{
ResumeThread(handle[0]);
}
#7
void CDxcTestDmDlg::OnButton1()
{
//线程1
handle[0]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,NULL,0,NULL);
//线程2
handle[1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc2,NULL,0,NULL);
WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);
}
这里的Wait函数在死等,界面线程已经停止响应了。你点不了Button2正常。
{
//线程1
handle[0]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,NULL,0,NULL);
//线程2
handle[1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc2,NULL,0,NULL);
WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);
}
这里的Wait函数在死等,界面线程已经停止响应了。你点不了Button2正常。
#8
WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);这个第三个参数改成FALSE。
这样Thread2退出,你的界面就能响应了。
这样Thread2退出,你的界面就能响应了。
#9
To ydfivy:
太对了,感谢!
不过我又有了一个新的问题。如果把线程函数2中的break注释掉,也就是说发现有字母a时(满足条件时),只是挂起线程1,但线程2仍继续循环检测(因为我可以把记事本B中的a手动删除掉),那么这样的话,线程2就永远退不出来,这样即使WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE)的第三个参数改成FALSE夜不好使了,那该怎么办呢??
太对了,感谢!
不过我又有了一个新的问题。如果把线程函数2中的break注释掉,也就是说发现有字母a时(满足条件时),只是挂起线程1,但线程2仍继续循环检测(因为我可以把记事本B中的a手动删除掉),那么这样的话,线程2就永远退不出来,这样即使WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE)的第三个参数改成FALSE夜不好使了,那该怎么办呢??
//第二个线程:每隔五秒,检测记事本B中是否出现了字母a,若出现了字母a,发出声音,并挂起线程1
unsigned int _stdcall ThreadFunc2(void *pm2)
{
VARIANT intXR,intYR,width,height;
dm2.SetPath("I:\\路径");
//绑定窗口
dm2.BindWindow(0x59063e,"gdi","windows","windows",0);
dm2.GetClientSize(0x59063e,&width,&height);
while(true)
{
Sleep(5000);
long find_rwret=dm2.FindPic(0,0,width.lVal,height.lVal,"a.bmp","020202",1,0,&intXR,&intYR);
if(find_rwret>=0)
{
dm2.Play("allsuccess.wav");
::SuspendThread(handle[0]);
//把break注释掉,也就是说发现有字母a时(满足条件时),只是挂起线程1,但线程2仍继续循环检测(因为我可以把记事本B中的a手动删除掉)
//break;
}
}
dm2.UnBindWindow();
return 0;
}
#10
啊O,好复杂。
呵呵。
办法就是把现在做的这些再移动一个工作线程里。然后根据上边那两个线程的状态,设置按钮是disable还是enable.
呵呵。
办法就是把现在做的这些再移动一个工作线程里。然后根据上边那两个线程的状态,设置按钮是disable还是enable.