C++中一个函数作为作为另一个函数的参数该如何解释
一个函数(actionfun)作为另一个函数的参数(mainfun),实际上是在运行主函数mainfun的时候,得到的一些数值传入到actionfun函数中,actionfun为主函数做一些设置也可以执行一些其他的功能,但都要从主函数mainfun中得到参数。 举例如下:
在.h中声明一个类型 和actionfun参数等一样
typedef int (*fun)(int tpart);
在.cpp中
int actionfun(int tpart)
{
//..........此处为执行函数,tpart为参数
return 0;
}
void mainfun(tag_t p_tag,fun actionfun)
{
//此处为执行代码....
//在执行打码中得到一个int值 假设为int int1
//将这个int1作为action的参数
(*actionfun)(int1);
}
大体就是这样使用的。
如何终止线程的运行(C/C++)
想要终止线程的运行,可以使用以下方法: 1、线程函数返回(最好使用该方法)。 2、通过调用ExitThread函数,线程将自行撤消(最好不使用该方法)。 3、同一个进程或另一个进程中的线程调用TerminateThread函数(应避免使用该方法)。 4、ExitProcess和TerminateProcess函数也可以用来终止线程的运行(应避免使用该方法)。下面将详细介绍终止线程运行的方法:1-4,并说明线程终止运行时会出现何种情况:5。 1、线程函数返回 始终都应该将线程设计成这样的形式,即当想要线程终止运行时,它们就能够返回。这是确保所有线程资源被正确地清除的唯一办法。 如果线程能够返回,就可以确保下列事项的实现: (1)在线程函数中创建的所有C++对象均将通过它们的撤消函数正确地撤消。 (2)操作系统将正确地释放线程堆栈使用的内存。 (3)系统将线程的退出代码(在线程的内核对象中维护)设置为线程函数的返回值。 (4)系统将递减线程内核对象的使用计数。 2、ExitThread函数 可以让线程调用ExitThread函数,以便强制线程终止运行: 函数原型:VOID ExitThread(DWORD dwExitCode); 该函数将终止线程的运行,并导致操作系统清除该线程使用的所有操作系统资源。但是,C++资源(如C++类对象)将不被撤消。由于这个原因,最好从线程函数返回,而不是通过调用ExitThread来返回。 当然,可以使用ExitThread的dwExitThread参数告诉系统将线程的退出代码设置为什么。ExitThread函数并不返回任何值,因为线程已经终止运行,不能执行更多的代码。 注意终止线程运行的最佳方法是让它的线程函数返回。但是,如果使用本节介绍的方法,应该知道ExitThread函数是Windows用来撤消线程的函数。如果编写C/C++代码,那么决不应该调用ExitThread。应该使用Visual C++运行期库函数_endthreadex。如果不使用Microsoft的Visual C++编译器,你的编译器供应商有它自己的ExitThread的替代函数。不管这个替代函数是什么,都必须使用。 3、TerminateThread函数 调用TerminateThread函数也能够终止线程的运行: 函数原型:BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode); 与ExitThread不同,ExitThread总是撤消调用的线程,而TerminateThread能够撤消任何线程。hThread参数用于标识被终止运行的线程的句柄。当线程终止运行时,它的退出代码成为你作为dwExitCode参数传递的值。同时,线程的内核对象的使用计数也被递减。 注意TerminateThread函数是异步运行的函数,也就是说,它告诉系统你想要线程终止运行,但是,当函数返回时,不能保证线程被撤消。如果需要确切地知道该线程已经终止运行,必须调用WaitForSingleObject或者类似的函数,传递线程的句柄。 设计良好的应用程序从来不使用这个函数,因为被终止运行的线程收不到它被撤消的通知。线程不能正确地清除,并且不能防止自己被撤消。 注意当使用返回或调用ExitThread的方法撤消线程时,该线程的内存堆栈也被撤消。但是,如果使用TerminateThread,那么在拥有线程的进程终止运行之前,系统不撤消该线程的堆栈。Microsoft故意用这种方法来实现TerminateThread。如果其他仍然正在执行的线程要引用强制撤消的线程堆栈上的值,那么其他的线程就会出现访问违规的问题。如果将已经撤消的线程的堆栈留在内存中,那么其他线程就可以继续很好地运行。 此外,当线程终止运行时, DLL通常接收通知。如果使用TerminateThread 强迫线程终止,DLL就不接收通知,这能阻止适当的清除。4、在进程终止运行时撤消线程 ExitProcess和TerminateProcess函数也可以用来终止线程的运行。差别在于这些线程将会使终止运行的进程中的所有线程全部终止运行。另外,由于整个进程已经被关闭,进程使用的所有资源肯定已被清除。这当然包括所有线程的堆栈。这两个函数会导致进程中的剩余线程被强制撤消,就像从每个剩余的线程调用TerminateThread一样。显然,这意味着正确的应用程序清除没有发生,即C++对象撤消函数没有被调用,数据没有转至磁盘等等。 5、线程终止运行时发生的操作 当线程终止运行时,会发生下列操作: (1)线程拥有的所有用户对象均被释放。在Windows中,大多数对象是由包含创建这些对象的线程的进程拥有的。但是一个线程拥有两个用户对象,即窗口和挂钩。当线程终止运行时,系统会自动撤消任何窗口,并且卸载线程创建的或安装的任何挂钩。其他对象只有在拥有线程的进程终止运行时才被撤消。 (2)线程的退出代码从STILL_ACTIVE改为传递给ExitThread或TerminateThread的代码。 (3)线程内核对象的状态变为已通知。 (4)如果线程是进程中最后一个活动线程,系统也将进程视为已经终止运行。 (5)线程内核对象的使用计数递减1。 当一个线程终止运行时,在与它相关联的线程内核对象的所有未结束的引用关闭之前,该内核对象不会自动被释放。 一旦线程不再运行,系统中就没有别的线程能够处理该线程的句柄。然而别的线程可以调用GetExitcodeThread来检查由hThread标识的线程是否已经终止运行。如果它已经终止运行,则确定它的退出代码: 函数原型:BOOL GetExitCodeThread( HANDLE hThread, PDWORD pdwExitCode); 退出代码的值在pdwExitCode指向的DWORD中返回。如果调用GetExitCodeThread时线程尚未终止运行,该函数就用STILL_ACTIVE标识符(定义为0x103)填入DWORD。如果该函数运行成功,便返回TRUE。
如何在线程程序外部彻底杀掉一个线程?
这个我试过,跟中止进程类似,用API: 1.取线程中止码:GetExitCodeThread((void *)thread->Handle,&ExitCode); 2.强行中止: TerminateThread((void *)thread->Handle,ExitCode);如此而已 这是一个死循环线程:__fastcall MyThread::MyThread(bool CreateSuspended) : TThread(CreateSuspended){}//---------------------------------------------------------------------------extern int js;void __fastcall MyThread::Execute(){ //---- Place thread code here ---- while (true) js++; // 死循环,不停地计数}======================================================//下面是主程序:#include #pragma hdrstop#include "Unit1.h"#include "Unit2.h"//---------------------------------------------------------------------------#pragma package(smart_init)#pragma resource "*.dfm"TForm1 *Form1;int js=0; // 全局变量 jsMyThread *thread=NULL;//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){}//---------------------------------------------------------------------------void __fastcall TForm1::Timer1Timer(TObject *Sender){ Edit1->Text=js; // 时钟不断显示js值}//---------------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender) // 运行线程{ if (thread==NULL) { thread= new MyThread(true); thread->Priority =tpHigher; thread->Resume(); // 线程运行 }}//---------------------------------------------------------------------------void __fastcall TForm1::Button2Click(TObject *Sender) // 中止线程{ if (thread!=NULL) { unsigned long ExitCode; if (!GetExitCodeThread((void *)thread->Handle,&ExitCode)) ShowMessage("得不到退出码,中止失败!"); else { if (TerminateThread((void *)thread->Handle,ExitCode)) { delete thread; thread=NULL; } else ShowMessage("中止失败!"); } }}中止线程后,Edit1的值就不再变化
C语言中如何让线程等待进程执行完一部分后,线程再继续执行
#include "afxmt.h"//全局变量CEvent event(FALSE, TRUE); //第二个参数为TRUE表示手动信号event.SetEvent( );//线程中要等待的地方WaitForSingleObject(event, INFINITE) //永远等待......//线程中的代码event.ResetEvent( ); //线程挂起//-----------------------------------------------------//以上代码C好像不行,可以用笨办法//定义一个全局标识变量int flag=0;//在线程中while(flag==0) //在主线程中改变flag的值,一旦不为0,则执行线程中的代码{ Sleep(1);}......//线程要执行的功能
delphi 在线程A中终止线程B
有三个解决办法。
第一个比较安全:
声明一个全局变量, 在线程2的循环过程中判断这个变量的值,如果是我们期望的值,则退出循环中止线程。
第二个方法,使用消息机制:
在线程循环中建立消息循环, 当接收到有指定的消息时退出循环中止线程。
第三个方法,直接使用API: TerminateThread
使用API TerminateThread 可以强行中止一个线程。 参考资料: http://baike.baidu.com/view/2311208.htm
VC如何关闭线程
你好,首先不建议你通过强行关闭线程的方式来结束音乐,你可能不知道,有个函数PlaySound可以已不播放,其用法如下:PlaySound("音乐位置",NULL,SND_ASYNC),这个函数结束起来也非常方便,PlaySound(NULL,NULL,NULL)就OK了,至于你关闭线程的问题,我也请教了几个人并测试,有些机器就停了,而我的跟你一样没停,很郁闷。如果有高手能说明下将感激不尽。
vc 如何释放线程资源
线程函数返回 这个线程就结束了 线程的内核对象就处于激发(有信号)状态。线程在创建后会返回一个线程内核对象(线程句柄),通过该内核对象可以强制结束该线程。如果线程创建后内核对象未使用也未关闭,这个内核对象资源就泄漏了。内核对象有引用次数的概念:线程创建,内核对象的引用次数是2,CloseHandle会使引用次数-1,线程结束内核对象的引用次数也会-1并处于激发状态,引用次数为0时释放资源并销毁。DWORD __stdcall aa(void *p){ return 0;}void main(){ CreateThread(0, 0, aa, 0, 0, 0); //内核对象泄漏}void main(){ HANDLE hthread = CreateThread(0, 0, aa, 0, 0, 0); CloseHandle(hthread); //无泄漏,线程函数结束内核对象销毁}