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

 更新时间:2020年4月25日 17:45  点击:2329
个人觉得在学习多线程编程之前最好先了解进程和线程的关系, 然后在学习线程工作方式的过程中动手写个(我是从抄开始的)多线程的小程序, 会对学习多线程有很大的帮助, 否则只有理论是很抽象的.

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

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

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

#include<windows.h>
#include<process.h>
#include<iostream>
using namespace std;
bool stop;
unsigned Counter;
unsigned __stdcall thread(void*)
{
cout <<"In second thread..." <<endl;
while (!stop){
Sleep(200);
cout <<Counter++ <<" " <<flush;
}
//_endthreadex(0);
return 0;
}
int main()
{
HANDLE hThread;
unsigned int threadID;
stop = false;
cout <<"Creating second thread..." <<endl;
// Create the second thread.
hThread = (HANDLE)_beginthreadex(NULL, 0, &thread, NULL, 0, &threadID);
// Wait until second thread terminates. If you comment out the line
// below, Counter will not be correct because the thread has not
// terminated, and Counter most likely has not been incremented to
// 1000000 yet.
//WaitForSingleObject(hThread, INFINITE);
system("pause");
stop = true;
//cin >>stop;
cout <<"Counter is-> " <<Counter <<endl;
// Destroy the thread object.
CloseHandle(hThread);
system("pause");
return 0;
}

代码是正确的, 复制粘贴到 Visual C++ 6.0 中, 即可编译运行. 但是会发现 _beginthreadex(...) 函数未定义的编译错误. 原因是因为我们的visual c++ 6.0 默认的是在单线程模式下编程, 如果需要进行多线程编程, 需要转换一下编译器的 '运行期库' , 方法很简单:
Project --> Settings --> C/C++ 中 选择 Category 中的 Code generation , 然后在 Use run-time library 里面选含有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还提供了一些库函数用来获得当前进程或者线程的句柄, 如 HANDLE GetCurrentProcess() 函数返回当前进程的句柄, HANDLE GetCurrentThread() 函数返回当前线程的句柄, 但是需要注意的是, 这些句柄都是 '伪句柄' , 即: 只在本进程和本线程内可用, 不可传出取用.

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

相关文章

  • C# WinForm多线程解决界面卡死问题的完美解决方案,使用BeginInvoke

    问题描述:当我们的界面需要在程序运行中不断更新数据时,当一个textbox的数据需要变化时,为了让程序执行中不出现界面卡死的现像,最好的方法就是多线程来解决一个主线程来创建界...2020-06-24
  • c# 多线程处理多个数据的方法

    这篇文章主要介绍了c# 多线程处理多个数据的方法,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-03-31
  • C#基于委托实现多线程之间操作的方法

    这篇文章主要介绍了C#基于委托实现多线程之间操作的方法,实例分析了C#的委托机制与多线程交互操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C#多线程中的异常处理操作示例

    这篇文章主要介绍了C#多线程中的异常处理操作,涉及C#多线程及异常的捕获、处理等相关操作技巧,需要的朋友可以参考下...2020-06-25
  • 深入分析C#中的异步和多线程

    这篇文章主要介绍了C#中异步和多线程的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2021-01-16
  • C#多线程与异步的区别详解

    多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别...2020-06-25
  • C#多线程之Thread类详解

    这篇文章主要为大家详细介绍了C#多线程之Thread类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • java中多线程与线程池的基本使用方法

    在Java中,我们可以利用多线程来最大化地压榨CPU多核计算的能力,下面这篇文章主要给大家介绍了关于java中多线程与线程池基本使用的相关资料,需要的朋友可以参考下...2021-09-13
  • C#中的多线程多参数传递详解

    第一种解决方案的原理是:将线程执行的方法和参数都封装到一个类里面。通过实例化该类,方法就可以调用属性来实现间接的类型安全地传递多个参数...2020-06-25
  • java多线程中执行多个程序的实例分析

    在本篇文章里小编给大家整理的是一篇关于java多线程中执行多个程序的实例分析内容,有需要的朋友们可以学习参考下。...2021-02-07
  • 解析C#多线程编程中异步多线程的实现及线程池的使用

    这篇文章主要介绍了C#多线程编程中异步多线程的实现及线程池的使用,同时对多线程的一般概念及C#中的线程同步并发编程作了讲解,需要的朋友可以参考下...2020-06-25
  • Windows配置VSCode+CMake+Ninja+Boost.Test的C++开发环境(教程详解)

    这篇文章主要介绍了Windows配置VSCode+CMake+Ninja+Boost.Test的C++开发环境,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-05-12
  • Springboot实现多线程注入bean的工具类操作

    这篇文章主要介绍了Springboot实现多线程注入bean的工具类操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-27
  • c# winform 关闭窗体时同时结束线程实现思路

    th.IsBackground = true解决线程问题,意思就是把线程设置为后台线程,感兴趣的朋友可以多了解下,如何有什么妙招还请多多指导哈...2020-06-25
  • VS Code C/C++环境配置教程(无法打开源文件“xxxxxx.h”或者检测到 #include 错误,请更新includePath)(POSIX API)

    这篇文章主要介绍了VS Code C/C++环境配置教程(无法打开源文件“xxxxxx.h” 或者 检测到 #include 错误。请更新includePath) (POSIX API),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-08-13
  • C#多线程编程中的锁系统(三)

    这篇文章主要介绍了C#多线程编程中的锁系统(三),本本文主要说下基于内核模式构造的线程同步方式、事件、信号量以及WaitHandle、AutoResetEvent、ManualResetEvent等内容,需要的朋友可以参考下...2020-06-25
  • Java多线程实现简易微信发红包的方法实例

    这篇文章主要给大家介绍了关于Java多线程实现简易微信发红包的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-01
  • c#使用多线程的几种方式示例详解

    这篇文章主要介绍了c#使用多线程的几种方式,通过示例学习c#的多线程使用方式,大家参考使用吧...2020-06-25
  • C#多线程编程中的锁系统(四):自旋锁

    这篇文章主要介绍了C#多线程编程中的锁系统(四):自旋锁,本文讲解了基础知识、自旋锁示例、SpinLock等内容,需要的朋友可以参考下...2020-06-25
  • C#多线程及同步示例简析

    这篇文章主要为大家详细介绍了C#多线程及同步示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25