C/C++多线程的学习心得总结
2023-06-13 09:15:00 时间
个人觉得在学习多线程编程之前最好先了解进程和线程的关系,然后在学习线程工作方式的过程中动手写个(我是从抄开始的)多线程的小程序,会对学习多线程有很大的帮助,否则只有理论是很抽象的.
在学习多线程编程之前,必须先知道什么是线程函数,线程函数就是另一个线程的入口函数.默认情况下一个我们所写的代码都是只有一个线程的,而这个线程的入口函数就是main()函数,这是系统默认的.而我们创建的另一个线程也需要一个函数来进入,这个函数就叫做线程函数.
在C/C++中,可以调用"运行期库"函数_beginthreadex(...),来创建一个线程,_beginthreadex(...)函数接受6个参数,其中第3个参数要求传入该线程的入口函数的地址(即:传入线程函数的函数名+&即可),其它的每个参数的意思可以在msdn或网上查一下,入门的话其余参数全部传0即可.
_beginthreadex(...)函数返回一个句柄,就是新线程的句柄.对于传入的线程函数是有要求的,线程函数必须返回unsigned__stdcall类型,并且接受一个void*型参数,函数的内容就可以自己定了.
先来段多线程的简单代码:
复制代码代码如下:
在学习多线程编程之前,必须先知道什么是线程函数,线程函数就是另一个线程的入口函数.默认情况下一个我们所写的代码都是只有一个线程的,而这个线程的入口函数就是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默认的是在单线程模式下编程,如果需要进行多线程编程,需要转换一下编译器的"运行期库",方法很简单:
这时再编译,就可以通过了.有了这个例子的函数,现在应该已经入门了吧.不过除了这个还有很多基础知识要补上,推荐通读几遍<windows核心编程(第四版)>的第6章.
实际上,在不同的编译环境下,_beginthreadex(...)函数可能会有不同的名称,但是它们都是对windows函数CreateThread(...)的封装,CreateThread(...)函数用来创建一个新的线程函数,CreateThread(...)函数同样接受6个参数,在类似_beginthreadex(...)的函数中对其做了一些安全的处理,如堆栈内存的申请等.虽然可以用CreateThread函数来创建一个新的线程,但是强烈建议使用_beginthreadex(...)函数,对于CreateThread函数在<windows核心编程(第四版)>第6章中有很好的讲解.
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()函数来关闭该句柄.
相关文章
- 多线程C语言_多线程c++
- 终极 C++避坑指南
- C++多线程编程:同步之互斥量Mutex「建议收藏」
- C++stl库_c++库
- 测试现代化硬件C++浮点数性能和一致性
- C++ STL 概述_严丝合缝的合作者
- c++的链表-C++实现简单链表
- C/C++ 实现多线程与线程同步
- C++11:多线程(1)
- c++基础
- C++多线程/原子性操作互斥锁
- C++面向对象程序设计(谭浩强)第三章第二~四节 学习笔记
- C++ priority_queue(STL priority_queue)用法详解
- MySQL中使用C操作实现多线程事务安全(c++ mysql 锁)
- C++开发:为什么多线程读写shared_ptr要加锁的详细介绍
- 深入C++中inline关键字的使用
- C++中栈结构建立与操作详细解析
- C++中给二维指针分配内存(实现代码)