zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C/C++多线程的学习心得总结

C++多线程 总结 学习心得
2023-06-13 09:15:00 时间
个人觉得在学习多线程编程之前最好先了解进程和线程的关系,然后在学习线程工作方式的过程中动手写个(我是从抄开始的)多线程的小程序,会对学习多线程有很大的帮助,否则只有理论是很抽象的.

在学习多线程编程之前,必须先知道什么是线程函数,线程函数就是另一个线程的入口函数.默认情况下一个我们所写的代码都是只有一个线程的,而这个线程的入口函数就是main()函数,这是系统默认的.而我们创建的另一个线程也需要一个函数来进入,这个函数就叫做线程函数.

在C/C++中,可以调用"运行期库"函数_beginthreadex(...),来创建一个线程,_beginthreadex(...)函数接受6个参数,其中第3个参数要求传入该线程的入口函数的地址(即:传入线程函数的函数名+&即可),其它的每个参数的意思可以在msdn或网上查一下,入门的话其余参数全部传0即可.

_beginthreadex(...)函数返回一个句柄,就是新线程的句柄.对于传入的线程函数是有要求的,线程函数必须返回unsigned__stdcall类型,并且接受一个void*型参数,函数的内容就可以自己定了.
先来段多线程的简单代码:
复制代码代码如下:

#include<windows.h>
#include<process.h>
#include<iostream>
usingnamespacestd;
boolstop;
unsignedCounter;
unsigned__stdcallthread(void*)
{
cout<<"Insecondthread..."<<endl;
while(!stop){
Sleep(200);
cout<<Counter++<<""<<flush;
}
//_endthreadex(0);
return0;
}
intmain()
{
HANDLEhThread;
unsignedintthreadID;
stop=false;
cout<<"Creatingsecondthread..."<<endl;
//Createthesecondthread.
hThread=(HANDLE)_beginthreadex(NULL,0,&thread,NULL,0,&threadID);
//Waituntilsecondthreadterminates.Ifyoucommentouttheline
//below,Counterwillnotbecorrectbecausethethreadhasnot
//terminated,andCountermostlikelyhasnotbeenincrementedto
//1000000yet.
//WaitForSingleObject(hThread,INFINITE);
system("pause");
stop=true;
//cin>>stop;
cout<<"Counteris->"<<Counter<<endl;
//Destroythethreadobject.
CloseHandle(hThread);
system("pause");
return0;
}

代码是正确的,复制粘贴到VisualC++6.0中,即可编译运行.但是会发现_beginthreadex(...)函数未定义的编译错误.原因是因为我们的visualc++6.0默认的是在单线程模式下编程,如果需要进行多线程编程,需要转换一下编译器的"运行期库",方法很简单:
Project-->Settings-->C/C++中选择Category中的Codegeneration,然后在Userun-timelibrary里面选含有Multithread的其中一个就可以了.
这时再编译,就可以通过了.有了这个例子的函数,现在应该已经入门了吧.不过除了这个还有很多基础知识要补上,推荐通读几遍<windows核心编程(第四版)>的第6章.
实际上,在不同的编译环境下,_beginthreadex(...)函数可能会有不同的名称,但是它们都是对windows函数CreateThread(...)的封装,CreateThread(...)函数用来创建一个新的线程函数,CreateThread(...)函数同样接受6个参数,在类似_beginthreadex(...)的函数中对其做了一些安全的处理,如堆栈内存的申请等.虽然可以用CreateThread函数来创建一个新的线程,但是强烈建议使用_beginthreadex(...)函数,对于CreateThread函数在<windows核心编程(第四版)>第6章中有很好的讲解.
当一个线程的任务结束,要退出时,有四种方法:
1.线程函数返回(最好使用这种方法);
2.通过调用_endthreadex()或ExitThread()函数,线程将自行撤消(最好不要使用这种方法);
3.同一个进程或另一个进程中的线程调用TerminateThread()函数(应该避免使用这种方法);
4.包含线程的进程终止运行(应该避免使用这种方法).
最好通过其入口函数的返回语句(即:return)来退出线程,也可以通过调用C/C++"运行期库"函数_endthreadex()函数来退出,还有两种退出的方法,都是类似的强制退出.最好使用线程函数的返回语句(return)来退出线程,只有这样才能安全的回收该线程的处理器资源和内存资源.而实际上_endthreadex()函数和_beginthreadex(...)函数一样,是封装了windows函数ExitThread(),如果一定要强制退出线程,那么强烈建议调用_endthreadex()函数,这样能安全的回收系统资源.

具体的_beginthreadex(...)函数和_endthreadex()函数在<windows核心编程(第四版)>第6章中有很好的剖析.同时还有两个_beginthread(...)和_endthread()运行期库函数,也有讲解.
windows还提供了一些库函数用来获得当前进程或者线程的句柄,如HANDLEGetCurrentProcess()函数返回当前进程的句柄,HANDLEGetCurrentThread()函数返回当前线程的句柄,但是需要注意的是,这些句柄都是"伪句柄",即:只在本进程和本线程内可用,不可传出取用.

如果需要在外部使用其它线程或进程的句柄,则可以用DuplicateHandle(...)函数获得其它进程或者线程的"实句柄",该函数接受7个参数,具体的用法可以查阅一下msdn和网络.需要注意的是,在使用完由DuplicateHandle(...)函数获得的句柄后,需要使用CloseHandle()函数来关闭该句柄.