【win32多线程】使用C++编写多线程

C++ 多线程(三) Win32多线程2 C++ 多线程(三) Win32多线程2 同步/资源共享 线程之间的同步 在下面的例子中,两个线程用于计算给定范围内的所有质数。 它演示了一个数字是否为质数的测试: #include <Windows.h> #include <process.h> #include <stdio.h> #include <math.h> volatile int counter = 0; int isPrime(int n) { for(int i = 2; i 阅读详情
1.以一个C++对象启动一个线程
 Q:如何以一个C++成员函数当做线程的起始函数?
 
错误的例子
#include <windows.h>
#include <stdio.h>
#include <process.h>


typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC)(
    LPVOID lpThreadParameter
    );
typedef unsigned *PBEGINTHREADEX_THREADID;




class ThreadObject
{
public:
    ThreadObject();
    void StartThread();
    virtual DWORD WINAPI ThreadFunc(LPVOID param);
    void WaitForExit();
private:
    HANDLE  m_hThread;
    DWORD m_ThreadId;
};


ThreadObject::ThreadObject()
{
    m_hThread = NULL;
    m_ThreadId = 0;
}


void ThreadObject::StartThread()
{
    m_hThread = (HANDLE)_beginthreadex(NULL,
                            0,
                            (PBEGINTHREADEX_THREADFUNC)ThreadFunc,
                            0,
                            0,
                            (PBEGINTHREADEX_THREADID)&m_ThreadId );
    if (m_hThread) {
        printf("Thread launched\n");
    }
}


void ThreadObject::WaitForExit()
{
    WaitForSingleObject(m_hThread, INFINITE);
    CloseHandle(m_hThread);
}


DWORD WINAPI ThreadObject::ThreadFunc(LPVOID param) //对类的成员函数默认有一个this参数
{
    // Do something useful ...


    return 0;
}


void main()
{
    ThreadObject obj;


    obj.StartThread();
    obj.WaitForExit();
}



正确的做法
为了以一个成员函数启动一个线程,要么使用静态成员函数,要么使用C函数,而非C++成员函数。这两种


技术的本质是相同的,但是静态成员函数的一个优点就是,它能够处理类的private成员变量和protected


成员变量。


由一个成员函数来启动一个线程范例:
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>


typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC)(
    LPVOID lpThreadParameter
    );
typedef unsigned *PBEGINTHREADEX_THREADID;


//
// This ThreadObject is created by a thread
// that wants to start another thread. All
// public member functions except ThreadFunc()
// are called by that original thread. The
// virtual function ThreadMemberFunc() is
// the start of the new thread.
//
class ThreadObject
{
public:
    ThreadObject();
    void StartThread();
    void WaitForExit();


    static DWORD WINAPI ThreadFunc(LPVOID param);


protected:
    virtual DWORD ThreadMemberFunc();


    HANDLE  m_hThread;
    DWORD   m_ThreadId;
};


ThreadObject::ThreadObject()
{
    m_hThread = NULL;
    m_ThreadId = 0;
}


void ThreadObject::StartThread()
{
    m_hThread = (HANDLE)_beginthreadex(NULL,
        0,
        (PBEGINTHREADEX_THREADFUNC) ThreadObject::ThreadFunc,
        (LPVOID)this,
        0,
        (PBEGINTHREADEX_THREADID) &m_ThreadId );
    if (m_hThread) {
        printf("Thread launched\n");
    }
}


void ThreadObject::WaitForExit()
{
    WaitForSingleObject(m_hThread, INFINITE);
    CloseHandle(m_hThread);
}


//
// This is a static member function.  Unlike
// C static functions, you only place the static
// declaration on the function declaration in the
// class, not on its implementation.
//
// Static member functions have no "this" pointer,
// but do have access rights.
//
DWORD WINAPI ThreadObject::ThreadFunc(LPVOID param)
{
    // Use the param as the address of the object
    ThreadObject* pto = (ThreadObject*)param;
    // Call the member function. Since we have a
    // proper object pointer, even virtual functions
    // will be called properly.
    return pto->ThreadMemberFunc();
}




//
// This above function ThreadObject::ThreadFunc()
// calls this function after the thread starts up.
//
DWORD ThreadObject::ThreadMemberFunc()
{
    // Do something useful ...
    return 0;
}




void main()
{
    ThreadObject obj;


    obj.StartThread();
    obj.WaitForExit();
}


在C++中如何利用构造函数和析构函数写一个比较安全的多线程程序,以及如何利用虚函数和多态等性质做


出一个可互换的锁定机制?


在C++中封装一个Critical section
class CriticalSection
{
public:
CriticalSection();
~CriticalSection();
void Enter();
void Leave();
private:
CRITICAL_SECTION m_CritSect;
}


CriticalSection::CriticalSection()
{
InitializeCriticalSection(&m_CritSect);
}


CriticalSection::~CriticalSection()
{
DeleteCriticalSection(&m_CritSect);
}
CriticalSection::Enter()
{
 EnterCriticalSection(&m_CritSect);
}


CriticalSection::Leave()
{
 LeaveCriticalSection(&m_CritSect);
}




在String类中使用CriticalSection类
Class String
{
  public:
  String();
  virtual ~String();
  virtual void Set(char *str);
int GetLength();
private:
CriticalSection m_Sync;
char * m_pData;
};


String::String()
{
 m_pData=NULL;
}
String::~String()
{
m_Sync.Enter();
delete []m_pData;
m_Sync.Leave();
}


void String::Set(char *str)
{
m_Sync.Enter();
delete [] m_pData;
m_pData=new char[::strlen(str)+1];
::strcpy(m_pData,str);
m_Sync.Leave();
}


int String::GetLength()
{
if(m_pData==NULL)
return 0;
m_Sync.Enter();
int len=::strlen(m_pData);
m_Sync.Leave();
return len;
}

这样就可以声明一个String变量,完全可以不了解Critical section,就可以获得同步效果。

----建立抽象的同步化对象
class Lock
{
 public:
Lock(CriticalSection *pCritsect);
~Lock();
private:
CriticalSection *m_pCritical;
};
Lock::Lock(CriticalSection *pCritsect)
{
m_pCritical=pCritsect;
EnterCriticalSection(&m_pCritical);
}


Lock::~Lock()
{
LeaveCriticalSection(&m_pCritical);
}

这个析构函数可以被自动调用,而critical section会被自动地解除锁定。绝对不会忘记将critical 

section解除锁定。

-------建立可互换的Lock

class LockableObject
{
public:
    LockableObject() {}
virtual ~ LockableObject(){}
virtual void Lock()=0;
virtual void UnLock()=0;
};
public CriticalSectionV2: public LockableObject
{
CriticalSectionV2();
virtual ~CriticalSectionV2();
virtual void Lock();
virtual void UnLock();
private:
CRITICAL_SECTION m_CritSect;
};
CriticalSectionV2::CriticalSectionV2()
{
InitializeCriticalSection(&m_CritSect);
}
CriticalSectionV2::~CriticalSectionV2()
{
DeleteCriticalSection(&m_CritSect);


}


CriticalSectionV2::Lock()
{
 EnterCriticalSection(&m_CritSect);
}
CriticalSectionV2::UnLock()
{
LeaveCriticalSection(&m_CritSect);
}


建立一个极安全又简单的Lock
class LockV2
{
public:
   LockV2(LockableObject *pLockable);
~LockV2();
private:
LockableObject * m_pLockable;
};
LockV2::LockV2(LockableObject *pLockable)
{
m_pLockable=pLockable;
m_pLockable->Lock();
}


LockV2::~LockV2()
{
 m_pLockable->UnLock();
}
上面用C++类取代Win32 API的直接调用
用安全又简单的“Lock”重写String 类
class StringV2
{
public:
StringV2();
virtual ~StringV2();
virtual void Set(char * str);
int getLength();
private:
CriticalSectionV2 m_Lockable;
char * m_pData;


};
StringV2::StringV2()
{
 m_pData=NULL;
}


StringV2::~StringV2()
{
delete [] m_pData;
}


void StringV2::Set(char *str)
{
LockV2 localLock(&m_Lockable);
delete [] m_pData;
 m_pData=NULL;
m_pData=new char[strlen(str)+1];
strcpy(m_pData,str);
}
int String::GetLength()
{
 LockV2 localLock(&m_Lockable);
if(m_pData==NULL)
return 0;
return ::strlen(m_pData);
}

C++ 多线程(二)Win32多线程1 C++ 多线程(二)Win32线程1 概述 Microsoft Windows 操作系统对多线程编程的支持几乎类似于 POSIX 线程提供的支持。区别不在于实际的功能,而在于 API 函数中的名称。 每个 Win32 进程至少有一个线程,我们将其称为主线程。我们将假设操作系统将以循环方式为每个程序线程提供一个时间片。事实上,Win32 程序中的线程将与其他程序中的线程和系统线程竞争 CPU,而这些其他线程可能有更高的优先级。 让我们看一下这个简单的例子。 主线程会生成一个新线程来增加 myThread 函 阅读详情

相关推荐

C++ 多线程之创建多线程CreateThread

一、为什么要写这篇博客一直对C++多线程一知半解,感觉没有实际进入过C++多线程的世界,因此想从头开始慢慢真正进入C++多线程,真正了解多线程。因为我也想了解Linux下的C++ 编程,因此我也会在Linux平台下进行编写代码并验证。文章里面会借鉴一些网上优秀的代码和讲解,但买一行代码我都会自己敲一遍,学习和借鉴是一起的,但代码必须是自己一行一行写的才行。这里的开头也是希望自己能记住自己的初衷!二、

~探路者~的博客 1万+

C++进阶—>Win32 多线程的创建方法和基本使用

Summary From:https://software.intel.com/zh-cn/blogs/2011/12/02/win32/?cid=sw:prccsdn2086 总结Win32提供的创建多线程相关的API接口和基本的使用框架。 Ref: MSDN: http://msdn.microsoft.com/zh-cn/library/y6h8hye8(v=VS.100)

小伟锅的博客 5787

[Win32] 多线程和线程同步

多线程:一个进程创建时,默认情况下系统会为它创建一个主线程,(如果使用Native API创建的线程就没有主线程,是空的,必须自己创建主线程),应用程序可以自己创建线程,还有以前写过的一篇“DLL注入技术”,就是远程在其他进程中创建线程,然后让远程线程load我们的dll。 系统是如何实现多线程的?其实,对于单CPU单核心的设备上,在一个确定的时刻,只能执行内存中的一个指令。所谓的“多任务抢占式

zuishikonghuan的博客 6266

C++多线程编程

今天我给大家讲一讲C++中的多线程编程技术,C++本身并没有提供任何多线程机制,但是在windows下,我们可以调用SDK win32 api来编写多线程的程序,下面我就此简单的讲一下:创建线程的函数  HANDLE CreateThread(     LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD    SIZE_T dwStackSize

ckh2007的专栏 3292

C++ 之win32多线程应用总结

C++ 之win32多线程应用总结

yohnyang的博客 517

深入理解基于Win32的C++线程池改进技术

本文还有配套的精品资源,点击获取 简介:线程池是一种多线程编程优化技术,通过预先创建和管理线程池来提高系统效率、减少开销并有效管理资源。在Windows平台上,基于Win32 API实现的C++线程池尤为常见。本改进版项目针对前版存在的问题进行了优化,包括解决崩溃和内存泄漏等多线程编程挑战。项目详细介绍了线程池的关键组件和实现细节,如线程管理、任务提交、同步机制、资源回收、...

weixin_35706255的博客 1126

OpenMP与C++:事半功倍地获得多线程的好处(上)

Kang Su Gatlin & Pete Isensee 著赖勇浩 译        在并行计算领域有一个广为流传的笑话——并行计算是未来之事并且永远都是。这个小笑话几十年来一直都是对的。一种类似的观点在计算机架构社区中流传,处理器时钟速度的极限似乎近在眼前,但时钟速度却一直在加快。多核革命是并行社区的乐观和架构社区的悲观的冲突。       现在主流的CPU厂商开始从追求时钟频

Richard的专栏 1137

瑞芯微RV1126B芯片实战:如何用3Tops NPU打造智能安防摄像头(附配置指南)

本文详细介绍了基于瑞芯微RV1126B芯片构建高性能智能安防摄像头的实战经验。文章深入剖析了其3Tops NPU与独立AI-ISP的协同优势,提供了从硬件选型、开发环境搭建、AI模型部署到系统调优的全流程配置指南,帮助开发者充分发挥芯片潜力,实现高效、稳定的智能视觉应用。

weixin_29281915的博客 443

c程序封装linux,Linux系统使用C语言封装线程读写锁

在Linux平台上已经有现成的线程读写锁pthread_rwlock_t以及相关API,现将这些API封装成与Win32平台上相同的接口,以便于编写跨平台程序。这些API包括pthread_rwlock_init,pthread_rwlock_rdlock,pthread_rwlock_tryrdlock,pthread_rwlock_wrlock,pthread_rwlock_trywrlock...

weixin_42371098的博客 276

【UE5.3 Cesium for Unreal】GlobePawn编译实战:从源码修改到功能实现

本文详细介绍了在UE5.3中为Cesium for Unreal插件编译和集成非官方增强组件GlobePawn的完整实战流程。从获取源码、准备资产文件、部署项目结构,到逐行修改代码适配工程并解决典型编译错误,最终实现在三维地球上实现类似Google Earth的丝滑鼠标交互体验。

weixin_29011667的博客 307

如何构建智能聊天系统

聊天分为听、思考、读,简单的通过ASR、LLM、TTS三类模型的组合可以实现,最近openai推出支持多模态的GPT-4o模型,可以把三个模型真正融合成在一起。现在市面上的模型百花齐放,各有所长。要实现可落地的方案,需要结合业务,验证模型效果,同时也要考虑方案的可行性,有些模型在国内能用,有些在国内不能用。

xsgnzb的专栏 2107

Win32和c++11多线程

如果这样加锁,那么只要有一个线程进入临界区,除非所有票卖完,否则不会释放临界区。如果这样加锁,又会出现卖出第0张票的情况。最后这种情况,修改代码,在进入临界区后再次判断,可以避免上述情况。

qq_24867003的博客 1568

【JS】自定义上传组件,文件上传与回显,自定义进度条显示(基于element-plus与axios)

公司是做B 端产品的,有sass平台也有源码交付的项目,最近开发了很多小系统,这里记录一下开发遇到的问题。 需要定制一个上传组件,要求可以自定义文件存储路径,自定义可上传的文件类型,限制文件大小等,并且提供基础的文件回显功能,例如上传一张图片到服务器指定目录的`/file`文件夹下面,并且实现可以查看预览的功能。

余浩的博客 1161

win32 C++多线程编程简单实例

今天我给大家讲一讲C++中的多线程编程技术,C++本身并没有提供任何多线程机制,但是在windows下,我们可以调用SDK win32 api来编写多线程的程序,下面我就此简单的讲一下:   创建线程的函数     HANDLE CreateThread(      LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD     SIZE_T d

wuqiyinglang的专栏 855

从零开始用TS开发babylonjs - 本机环境搭建

babylonjs,初始化本地安装,web3d引擎

han3527638的专栏 793

ResNet改进(7):添加 SK注意力机制

实现 SK 注意力机制。

2401_82355416的博客 731

使用 C 和 Win32 进行多线程编程

本文转自http://msdn.microsoft.com/zh-cn/library/y6h8hye8(VS.80).aspx &nbsp; MicrosoftVisual C++ 支持在 MicrosoftWindows(Windows&nbsp;XP、Windows&nbsp;2000、Windows&nbsp;NT、Windows&nbsp;Me 和Windows&...

Windows SDK 515

60、磁悬浮主动隔振系统的LQR控制研究

本研究针对磁悬浮主动隔振系统,提出了一种结合ANN建模、LQR控制与MPGA优化的综合控制方案。通过建立系统的动力学与状态空间模型,利用混合训练算法的ANN精确描述MSVI的非线性和滞后特性,并设计基于最小力传递率的LQR控制器。为优化LQR的Q和R矩阵,引入多群体遗传算法(MPGA),有效克服传统GA的早熟收敛问题,提升搜索效率与控制性能。仿真结果表明,在单频、扫频、随机及冲击激励下,该方法显著降低传递力幅值,隔振效果远优于被动系统。研究验证了所提方法的有效性,为磁悬浮隔振技术的实际应用奠定了基础,并展望

linux6sysadmin的博客 125

线程与进程编程:C++中的五种通信方式、死锁及Win32多线程详解

线程与进程编程:C++中的五种通信方式及Win32多线程详解

re1ife的博客 2078

串口通信协议

文章目录前言一、串口通信结构图二、电平三、串口通信协议 前言 本文记录的是平时常用的串口通信有关知识点 提示:以下是本篇文章正文内容,下面案例可供参考 一、串口通信结构图 1、RS232标准串口通讯结构图 2、USB转串口通讯结构图 3、原生的串口到串口 二、电平 串口通信的时候,有三种电平:TTL电平、RS232电平、USB电平 TTL电平是从MCU直接出来的电平 RS323是一种通讯标准,因为高电平+15V低电平–15V电位差30V容错空间大,抗干扰能力强,一般用于工业设备直接通信电平转换芯

weixin_43772611的博客 6847

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

win32多线程和C++11多线程对比

C++11的mutex和thread虽然使用更加方便快捷,具有跨平台的有点,但是效率相比较于win32的多线程,效率有了明显的降低,故优先考win32多线程。

pkx1993的博客 1321

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

使用 acl_cpp 库编写多线程程序

在 《利用ACL库开发高并发半驻留式线程池程序》中介绍了如何使用 C 版本的 acl 线程库编写多线程程序,本文将会介绍如何使用 C++ 版本的 acl 线程库编写多线程程序,虽然 C++ 版 acl 线程库基于 C 版的线程库,但却提供了更为清晰简洁的接口定义(很多地方参考了 JAVA 的线程接口定义)。下面是一个简单的使用线程的例子: #include "acl_cpp/lib_acl.hp

zsxxsz的专栏 1851

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Win32下两种用于C++的线程同步类(多线程实现加锁解锁)

http://blog.youkuaiyun.com/theplayerwuliang/article/details/6431722 Win32下两种用于C++的线程同步类(多线程实现加锁解锁) 线程同步是多线程程序设计的核心内容,它的目的是正确处理多线程并发时的各种问题,例如线程的等待、多个线程访问同一数据时的互斥,防死锁等。Win32提供多种内核对象和手段用于线程同步,如

孙建军的博客 962

win32线程退出C语言,多线程在C、Win32和MFC下的使用方法

下载源代码一.前言线程是执行路径。一个进程至少要有一个线程,也可能包含多个线程。若进程关闭了,则在进程中所有的线程也自动被销毁。当我们在一个应用程序中创建一个线程时,实际上,它是第二个线程。在C或C++中,程序的入口函数是main或wmain(Unicode版本)。在windows的运用程序中,程序的入口点是WinMain或wWinMain。当程序启动时,操作系统创建第一个线程。因此,window...

weixin_35637837的博客 583

win32多线程编程

一、问题的提出 编写一个耗时的单线程程序:   新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX_SECOND,标题为“延时6秒”,添加按钮的响应函数,代码如下:  void CSingleThreadDlg::OnSleepSixSecond()  {  Sleep(

579

Log4cpp介绍及使用

Log4cpp是一个开源的C++类库,它提供了在C++程序中使用日志和跟踪调试的功能。使用log4cpp,可以很便利地将日志或者跟踪调试信息写入字符流、内存字符串队列、文件、回滚文件、调试器、Windows日志、本地syslog和远程syslog服务器中。 1、Log4cpp简介   Log4cpp是个基于LGPL的开源项目,移植自Java的日志处理跟踪项目log4j,并保持了API上的一致。

Ckary的博客 5万+
上一篇: 【Win32多线程】使用C runtime Library
下一篇: 【C++STL】C++ Standard Template Library三个重要元素
xiaoding133
博客等级 码龄19年 415粉丝 159原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值