GetExitCodeThread()

本文详细介绍了GetExitCodeThread函数的使用方法及其在多线程应用中的作用。该函数用于获取线程的退出代码,从而判断线程是否已结束执行。文章通过一个示例程序展示了如何使用该函数监测两个线程的状态。

 

BOOL   GetExitCodeThread (

       HANDLE         hThread,                  // in,线程handle,也就是CreateThread()的返回值

       LPDWORD      lpExitCode               //out,存储线程结束代码,也就是线程的返回值

);

说明: 此函数调用成功返回TRUE,失败返回FALSE,只表示这个函数是否调用成功而己.

        不能根据返回值来判断一个线程是否结束,而要根据 lpExitCode的值来确定,

        lpExitCode  值STILL_ACTIVE 表示线程正在运行.

            若线程己经结束,则lpExitCode中存储指定线程的返回值.

例:

 

 

#pragma once #include "MsGlobal.h" #include <windows.h> #include <process.h> #include "hid/hidapi.h" #pragma comment (lib,"setupapi.lib") using namespace std; struct sBuff { sBuff() { stop = 0; len = 0; memset(udata, 0, 10240); } int stop; int len; unsigned char udata[10240]; }; class ComBase { public: ComBase(); ~ComBase(); int InitUSB(unsigned short vid, unsigned short pid); int OpenUSB(unsigned short vid, unsigned short pid); void CloseUSB(); public: int SendMsg(unsigned char* Send, size_t nLength); int ReceiveMsg(unsigned char* pReceiveBuf, size_t& nLength); int getDevStatus() { return handle ? 0 : 1; } hid_device *getHID() { return this->handle; } sBuff *getBuff() { return this->m_pBuff; } void setBuff(sBuff *pBuff) { this->m_pBuff = pBuff; } private: hid_device *handle; sBuff *m_pBuff; }; #include "ComBase.h" #include "algorithm/GCS_Encrypt.h" #include "files/logFile.h" ComBase::ComBase() { handle = nullptr; m_pBuff = new sBuff(); } ComBase::~ComBase() { if (handle) CloseUSB(); delete m_pBuff; m_pBuff = nullptr; } int ComBase::InitUSB(unsigned short vid, unsigned short pid) { if (hid_init())//实际上不调用它hid_enumerate和下面的hid_open也会自动调用 return -1; hid_device_info* Hids, *HidsCopy;//一个用于接收设备信息的单链表,另一个用来遍历,该结构体使用unicode编码,所以下面都要用unicode处理方式 Hids = hid_enumerate(vid, pid);//获取vid为0x154F,pid为0x4304的HID设备链表,这里如果都是0就是获取所有的HID设备 HidsCopy = Hids; LPCWSTR wpSerialNumber = L"\0";//用来去重,一个hid设备一般有多个端点,因此会读到多个 while (HidsCopy) { if (CompareStringW(LOCALE_INVARIANT, NORM_LINGUISTIC_CASING, wpSerialNumber, -1, HidsCopy->serial_number, -1) != CSTR_EQUAL)//去重 { xPrintf((LPCTSTR)HidsCopy->serial_number); wpSerialNumber = HidsCopy->serial_number;//我这里只需要序列号,实际上这个结构体还有很多数据,可以参考官方的实例 } HidsCopy = HidsCopy->next; } hid_free_enumeration(Hids);//释放设备链表 return 0; } /********************************************************* 函数名称: OpenUSB(LPCTSTR PscSerialNumber) 函数功能: 打开USB-HID设备 输入参数: 参数1: LPCTSTR PscSerialNumber - HID设备的序列号 返回值: 成功 - 0 失败 - -1 ********************************************************/ int ComBase::OpenUSB(unsigned short vid, unsigned short pid) { if (MsGlobal::m_VirtualVer == VER_VIRTUAL) { return 0; } if (handle) CloseUSB(); handle = hid_open(vid, pid, NULL);//打开指定vid、pid、序列号的设备 if (!handle) { xPrintf("无法打开USB设备"); hid_exit(); return -1; } // 将hid_read()函数设置为非阻塞。 if (hid_set_nonblocking(handle, 1) != 0)// 1启用非阻塞 0禁用非阻塞。 { xPrintf("设置非阻塞失败"); hid_close(handle); hid_exit(); return -2; } return 0; } //关闭USB-HID设备 /********************************************************* 函数名称: CloseUSB(hid_device*& handle) 函数功能: 关闭USB-HID设备 输入参数: 参数1: hid_device*& handle - 操作句柄 ********************************************************/ void ComBase::CloseUSB() { if (MsGlobal::m_VirtualVer == VER_VIRTUAL) { return; } if (handle) { hid_close(handle); hid_exit(); } handle = nullptr;//这里将指针置空,增强安全性 } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // 线程执行的函数 unsigned int WINAPI ThreadSendMsg(LPVOID lpThreadParameter) { ComBase *m_pDev = (ComBase *)lpThreadParameter; if (!m_pDev) { xPrintf("lpThreadParameter error"); return -1; } sBuff *pBuff = m_pDev->getBuff(); if (!pBuff || pBuff->len == 0) { xPrintf("getBuff error"); return -2; } hid_device *handle = m_pDev->getHID(); if (handle == INVALID_HANDLE_VALUE) { xPrintf("getHID error"); return -3; } // 读取数据并清空缓存 int leftNum = 1; while (leftNum) { unsigned char buf[1024]; memset(buf, 0, 1024); leftNum = hid_read_timeout(handle, buf, sizeof(buf), 0); if (leftNum < 0) { xPrintf("hid_read_timeout error"); return -4; } } // 此处对消息进行加密,从第三个字节开始 GCS_Msg_Encryption(secret::KEY_COMMUNICATION, sizeof(secret::KEY_COMMUNICATION), &pBuff->udata[2], pBuff->udata[1]); // 此处分包,目前支持64个字节(加上id一共65个字节) int size = 64; int packs = pBuff->len / size * size; if (pBuff->len % size != 0) { packs++; } int result = 0; for (int i = 0; i < packs; i++) { int rlen = size; if (i * size > pBuff->len) rlen = pBuff->len - (i - 1) * size; UCHAR OutputReport[65]; memset(OutputReport, 0, 65); memcpy(&OutputReport[1], &pBuff->udata[i * size], rlen); int iResp = hid_write(handle, OutputReport, 65); if (iResp < 0) { xPrintf("hid_write error"); result = -5; break; } } ExitThread(result); } int ComBase::SendMsg(unsigned char* Send, size_t nLength) { /// 初始化缓存 this->m_pBuff->stop = 0; this->m_pBuff->len = nLength; memcpy(this->m_pBuff->udata, Send, nLength); /// 启动发送线程 unsigned int dwThreadID; HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadSendMsg, (void *)this, 0, &dwThreadID); if (hThread == NULL) { xPrintf("_beginthreadex Error!"); return -1; } /// 线程阻塞 DWORD wr = WaitForSingleObject(hThread, 3000); switch (wr) { case WAIT_FAILED: { xPrintf("thread wait failed"); this->m_pBuff->stop = 1; CloseHandle(hThread); return -2; } break; case WAIT_TIMEOUT: { xPrintf("thread wait timeout"); this->m_pBuff->stop = 1; CloseHandle(hThread); return -3; } break; default: break; } /// 获取线程函数的返回值 DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); if (dwExitCode != 0) { xPrintf("thread exit code error"); CloseHandle(hThread); return -4; } CloseHandle(hThread); return 0; } // 线程执行的函数 unsigned int WINAPI ThreadReceiveMsg(LPVOID lpThreadParameter) { ComBase *m_pDev = (ComBase *)lpThreadParameter; if (!m_pDev) { xPrintf("lpThreadParameter error"); return -1; } sBuff *pBuff = m_pDev->getBuff(); if (!pBuff || pBuff->len != 0) { xPrintf("getBuff error"); return -2; } hid_device *handle = m_pDev->getHID(); if (handle == INVALID_HANDLE_VALUE) { xPrintf("getHID error"); return -3; } int result = 0; while (!pBuff->stop) { UCHAR recvDataBuf[1024]; memset(recvDataBuf, 0, 1024); int len = hid_read(handle, recvDataBuf, 65); if (len > 0) { memcpy(&pBuff->udata[pBuff->len], recvDataBuf, len); pBuff->len += len; if (pBuff->udata[0] != 0xE5) {/// 无效数据 xPrintf("read data exception\n"); result = -4; break; } else {/// 有效数据 int msglen = pBuff->udata[1] + 2; if (msglen <= pBuff->len) {/// 接收完成 // 此处对消息进行解密,从第三个字节开始 GCS_Msg_Decrypt(secret::KEY_COMMUNICATION, sizeof(secret::KEY_COMMUNICATION), &pBuff->udata[2], pBuff->udata[1]); //计算crc16 uint16_t crc = crc16_modbus(&pBuff->udata[0], msglen - 2); uint8_t crc_low = crc & 0xFF; uint8_t crc_high = (crc >> 8) & 0xFF; if (crc_low != pBuff->udata[msglen - 1] || crc_high != pBuff->udata[msglen - 2]) { xPrintf("crc error\n"); result = -5; break; } else { xPrintf("read data finish\n"); result = 0; break; } } else {/// 接收未完成 xPrintf("read data unfinish\n"); continue; } } } } ExitThread(result); } int ComBase::ReceiveMsg(unsigned char* pReceiveBuf, size_t& nLength) { /// 刷新缓存 this->m_pBuff->stop = 0; this->m_pBuff->len = 0; memset(this->m_pBuff->udata, 0, 10240); /// 启动接收线程 unsigned int dwThreadID; HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadReceiveMsg, (void *)this, 0, &dwThreadID); if (hThread == NULL) { xPrintf("_beginthreadex error!"); return -1; } /// 线程阻塞 DWORD wr = WaitForSingleObject(hThread, 3000); switch (wr) { case WAIT_FAILED: { xPrintf("thread wait failed"); this->m_pBuff->stop = 1; CloseHandle(hThread); return -2; } break; case WAIT_TIMEOUT: { xPrintf("thread wait timeout"); this->m_pBuff->stop = 1; CloseHandle(hThread); return -3; } break; default: break; } /// 获取线程函数的返回值 DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); if (dwExitCode != 0) { xPrintf("thread exit code error"); CloseHandle(hThread); return -4; } /// 根据协议拷贝有效的消息部分 nLength = this->m_pBuff->udata[1] + 2; memcpy(pReceiveBuf, this->m_pBuff->udata, nLength); CloseHandle(hThread); return 0; }#pragma once #include "MsGlobal.h" #include <windows.h> #include <process.h> #include "hid/hidapi.h" #pragma comment (lib,"setupapi.lib") using namespace std; struct sBuff { sBuff() { stop = 0; len = 0; memset(udata, 0, 10240); } int stop; int len; unsigned char udata[10240]; }; class ComBase { public: ComBase(); ~ComBase(); int InitUSB(unsigned short vid, unsigned short pid); int OpenUSB(unsigned short vid, unsigned short pid); void CloseUSB(); public: int SendMsg(unsigned char* Send, size_t nLength); int ReceiveMsg(unsigned char* pReceiveBuf, size_t& nLength); int getDevStatus() { return handle ? 0 : 1; } hid_device *getHID() { return this->handle; } sBuff *getBuff() { return this->m_pBuff; } void setBuff(sBuff *pBuff) { this->m_pBuff = pBuff; } private: hid_device *handle; sBuff *m_pBuff; }; #include "ComBase.h" #include "algorithm/GCS_Encrypt.h" #include "files/logFile.h" ComBase::ComBase() { handle = nullptr; m_pBuff = new sBuff(); } ComBase::~ComBase() { if (handle) CloseUSB(); delete m_pBuff; m_pBuff = nullptr; } int ComBase::InitUSB(unsigned short vid, unsigned short pid) { if (hid_init())//实际上不调用它hid_enumerate和下面的hid_open也会自动调用 return -1; hid_device_info* Hids, *HidsCopy;//一个用于接收设备信息的单链表,另一个用来遍历,该结构体使用unicode编码,所以下面都要用unicode处理方式 Hids = hid_enumerate(vid, pid);//获取vid为0x154F,pid为0x4304的HID设备链表,这里如果都是0就是获取所有的HID设备 HidsCopy = Hids; LPCWSTR wpSerialNumber = L"\0";//用来去重,一个hid设备一般有多个端点,因此会读到多个 while (HidsCopy) { if (CompareStringW(LOCALE_INVARIANT, NORM_LINGUISTIC_CASING, wpSerialNumber, -1, HidsCopy->serial_number, -1) != CSTR_EQUAL)//去重 { xPrintf((LPCTSTR)HidsCopy->serial_number); wpSerialNumber = HidsCopy->serial_number;//我这里只需要序列号,实际上这个结构体还有很多数据,可以参考官方的实例 } HidsCopy = HidsCopy->next; } hid_free_enumeration(Hids);//释放设备链表 return 0; } /********************************************************* 函数名称: OpenUSB(LPCTSTR PscSerialNumber) 函数功能: 打开USB-HID设备 输入参数: 参数1: LPCTSTR PscSerialNumber - HID设备的序列号 返回值: 成功 - 0 失败 - -1 ********************************************************/ int ComBase::OpenUSB(unsigned short vid, unsigned short pid) { if (MsGlobal::m_VirtualVer == VER_VIRTUAL) { return 0; } if (handle) CloseUSB(); handle = hid_open(vid, pid, NULL);//打开指定vid、pid、序列号的设备 if (!handle) { xPrintf("无法打开USB设备"); hid_exit(); return -1; } // 将hid_read()函数设置为非阻塞。 if (hid_set_nonblocking(handle, 1) != 0)// 1启用非阻塞 0禁用非阻塞。 { xPrintf("设置非阻塞失败"); hid_close(handle); hid_exit(); return -2; } return 0; } //关闭USB-HID设备 /********************************************************* 函数名称: CloseUSB(hid_device*& handle) 函数功能: 关闭USB-HID设备 输入参数: 参数1: hid_device*& handle - 操作句柄 ********************************************************/ void ComBase::CloseUSB() { if (MsGlobal::m_VirtualVer == VER_VIRTUAL) { return; } if (handle) { hid_close(handle); hid_exit(); } handle = nullptr;//这里将指针置空,增强安全性 } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // 线程执行的函数 unsigned int WINAPI ThreadSendMsg(LPVOID lpThreadParameter) { ComBase *m_pDev = (ComBase *)lpThreadParameter; if (!m_pDev) { xPrintf("lpThreadParameter error"); return -1; } sBuff *pBuff = m_pDev->getBuff(); if (!pBuff || pBuff->len == 0) { xPrintf("getBuff error"); return -2; } hid_device *handle = m_pDev->getHID(); if (handle == INVALID_HANDLE_VALUE) { xPrintf("getHID error"); return -3; } // 读取数据并清空缓存 int leftNum = 1; while (leftNum) { unsigned char buf[1024]; memset(buf, 0, 1024); leftNum = hid_read_timeout(handle, buf, sizeof(buf), 0); if (leftNum < 0) { xPrintf("hid_read_timeout error"); return -4; } } // 此处对消息进行加密,从第三个字节开始 GCS_Msg_Encryption(secret::KEY_COMMUNICATION, sizeof(secret::KEY_COMMUNICATION), &pBuff->udata[2], pBuff->udata[1]); // 此处分包,目前支持64个字节(加上id一共65个字节) int size = 64; int packs = pBuff->len / size * size; if (pBuff->len % size != 0) { packs++; } int result = 0; for (int i = 0; i < packs; i++) { int rlen = size; if (i * size > pBuff->len) rlen = pBuff->len - (i - 1) * size; UCHAR OutputReport[65]; memset(OutputReport, 0, 65); memcpy(&OutputReport[1], &pBuff->udata[i * size], rlen); int iResp = hid_write(handle, OutputReport, 65); if (iResp < 0) { xPrintf("hid_write error"); result = -5; break; } } ExitThread(result); } int ComBase::SendMsg(unsigned char* Send, size_t nLength) { /// 初始化缓存 this->m_pBuff->stop = 0; this->m_pBuff->len = nLength; memcpy(this->m_pBuff->udata, Send, nLength); /// 启动发送线程 unsigned int dwThreadID; HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadSendMsg, (void *)this, 0, &dwThreadID); if (hThread == NULL) { xPrintf("_beginthreadex Error!"); return -1; } /// 线程阻塞 DWORD wr = WaitForSingleObject(hThread, 3000); switch (wr) { case WAIT_FAILED: { xPrintf("thread wait failed"); this->m_pBuff->stop = 1; CloseHandle(hThread); return -2; } break; case WAIT_TIMEOUT: { xPrintf("thread wait timeout"); this->m_pBuff->stop = 1; CloseHandle(hThread); return -3; } break; default: break; } /// 获取线程函数的返回值 DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); if (dwExitCode != 0) { xPrintf("thread exit code error"); CloseHandle(hThread); return -4; } CloseHandle(hThread); return 0; } // 线程执行的函数 unsigned int WINAPI ThreadReceiveMsg(LPVOID lpThreadParameter) { ComBase *m_pDev = (ComBase *)lpThreadParameter; if (!m_pDev) { xPrintf("lpThreadParameter error"); return -1; } sBuff *pBuff = m_pDev->getBuff(); if (!pBuff || pBuff->len != 0) { xPrintf("getBuff error"); return -2; } hid_device *handle = m_pDev->getHID(); if (handle == INVALID_HANDLE_VALUE) { xPrintf("getHID error"); return -3; } int result = 0; while (!pBuff->stop) { UCHAR recvDataBuf[1024]; memset(recvDataBuf, 0, 1024); int len = hid_read(handle, recvDataBuf, 65); if (len > 0) { memcpy(&pBuff->udata[pBuff->len], recvDataBuf, len); pBuff->len += len; if (pBuff->udata[0] != 0xE5) {/// 无效数据 xPrintf("read data exception\n"); result = -4; break; } else {/// 有效数据 int msglen = pBuff->udata[1] + 2; if (msglen <= pBuff->len) {/// 接收完成 // 此处对消息进行解密,从第三个字节开始 GCS_Msg_Decrypt(secret::KEY_COMMUNICATION, sizeof(secret::KEY_COMMUNICATION), &pBuff->udata[2], pBuff->udata[1]); //计算crc16 uint16_t crc = crc16_modbus(&pBuff->udata[0], msglen - 2); uint8_t crc_low = crc & 0xFF; uint8_t crc_high = (crc >> 8) & 0xFF; if (crc_low != pBuff->udata[msglen - 1] || crc_high != pBuff->udata[msglen - 2]) { xPrintf("crc error\n"); result = -5; break; } else { xPrintf("read data finish\n"); result = 0; break; } } else {/// 接收未完成 xPrintf("read data unfinish\n"); continue; } } } } ExitThread(result); } int ComBase::ReceiveMsg(unsigned char* pReceiveBuf, size_t& nLength) { /// 刷新缓存 this->m_pBuff->stop = 0; this->m_pBuff->len = 0; memset(this->m_pBuff->udata, 0, 10240); /// 启动接收线程 unsigned int dwThreadID; HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadReceiveMsg, (void *)this, 0, &dwThreadID); if (hThread == NULL) { xPrintf("_beginthreadex error!"); return -1; } /// 线程阻塞 DWORD wr = WaitForSingleObject(hThread, 3000); switch (wr) { case WAIT_FAILED: { xPrintf("thread wait failed"); this->m_pBuff->stop = 1; CloseHandle(hThread); return -2; } break; case WAIT_TIMEOUT: { xPrintf("thread wait timeout"); this->m_pBuff->stop = 1; CloseHandle(hThread); return -3; } break; default: break; } /// 获取线程函数的返回值 DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); if (dwExitCode != 0) { xPrintf("thread exit code error"); CloseHandle(hThread); return -4; } /// 根据协议拷贝有效的消息部分 nLength = this->m_pBuff->udata[1] + 2; memcpy(pReceiveBuf, this->m_pBuff->udata, nLength); CloseHandle(hThread); return 0; } 这段代码实现了什么功能,让我读懂每一行代码
09-03
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值