QThead实现模拟VC线程函数

// 头文件
#ifndef QTHREADBASE_H
#define QTHREADBASE_H

#include <iostream>
#include <stdlib.h>
#include <qmutex.h>
#include <Qthread.h>
#include <list>

#ifdef _MAC
#define CALLBACK    PASCAL
#define WINAPI      CDECL
#define WINAPIV     CDECL
#define APIENTRY    WINAPI
#define APIPRIVATE  CDECL
#ifdef _68K_
#define PASCAL      __pascal
#else
#define PASCAL
#endif
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define CALLBACK    __stdcall
#define WINAPI      __stdcall
#define WINAPIV     __cdecl
#define APIENTRY    WINAPI
#define APIPRIVATE  __stdcall
#define PASCAL      __stdcall
#else
#define CALLBACK
#define WINAPI
#define WINAPIV
#define APIENTRY    WINAPI
#define APIPRIVATE
#define PASCAL      pascal
#endif

class CThread: public QThread
{
public:
    CThread();
    virtual ~CThread();
public:
    // 设置等待超时
    void SetTimOut(unsigned long dwTimeOut = ULONG_MAX);
    // 获取等待超时
    unsigned long  GetTimeOut();
    // 允许线程强制退出
    void EnableTerminateThread(bool bEnable = false);
    bool IsEnableTerminateThread();
    // 线程退出标志
    bool IsQuit();
    // 设置线程退出标示
    void SetQuit(bool bQuit);
    // 线程延迟
    void ThreadSleep(unsigned long dwTime);
    // 启动线程
    bool StartThread(void (WINAPI *ThreadFun)(void* pParam) ,Priority nPriority = NormalPriority,void* ThreadParam = NULL);
    // 设置线程权限
    bool SetThreadPriority(Priority priority);
    // 恢复线程
    unsigned long ResumeThread();
    // 挂起线程
    unsigned long SuspendThread();
    // 设置线程与CPU某个核运行
    unsigned long SetThreadAffinityMask(unsigned long dwThreadAffinityMask);
    // 等待线程退出
    bool WaitQuit(unsigned long dwMilliseconds);
    // 强制杀掉线程
    bool TerminateThread();
public:
    void SetCustomData(void *lpData);
    void *GetCustomData();
private:
    void run();
private:
    void (WINAPI *FUN_ThreadFun)(void* pParam);
    void*    m_lpThreadParam;

    unsigned long m_dwTimeOut;
    // 允许强行杀线程
    bool m_bEnableForceKill;
    bool m_bAllowExit;
    // 自定用户参数
    void *m_lpCustomData;
};

#endif // QTHREADBASE_H
// cpp文件
#include "Thread.h"

CThread::CThread()
{
    m_dwTimeOut = ULONG_MAX;
    m_bEnableForceKill = false;
    SetQuit(false);

    m_lpCustomData = NULL;
}
CThread::~CThread()
{
    SetQuit(true);
    if(!IsEnableTerminateThread())
    {
        if(!WaitQuit(m_dwTimeOut))
        {
            TerminateThread();
        }
    }
    else
    {
        TerminateThread();
    }
}
void CThread::SetCustomData(void *lpData)
{
    m_lpCustomData = lpData;
}

void *CThread::GetCustomData()
{
    return m_lpCustomData;
}

void CThread::run()
{
    if(FUN_ThreadFun)
    {
        FUN_ThreadFun(m_lpThreadParam);
    }
}

bool CThread::WaitQuit(unsigned long dwMilliseconds)
{
    return wait(dwMilliseconds);
}
void CThread::EnableTerminateThread(bool bEnable)
{
    m_bEnableForceKill = bEnable;
}
bool CThread::IsEnableTerminateThread()
{
    return m_bEnableForceKill;
}

void CThread::SetTimOut(unsigned long dwTimeOut)
{
    m_dwTimeOut = dwTimeOut;
}
unsigned long CThread::GetTimeOut()
{
    return m_dwTimeOut;
}
bool CThread::IsQuit()
{
    return m_bAllowExit;
}
void CThread::SetQuit(bool bQuit)
{
    m_bAllowExit = bQuit;
}
void CThread::ThreadSleep(unsigned long dwTime)
{
    if( dwTime > 10)
    {
        unsigned int dwCount = 0;
        while(!IsQuit())
        {
            QThread::msleep(10);

            if(++dwCount > (unsigned int)(dwTime / 10))
            {
                break;
            }
        }
    }
    else
    {
        QThread::msleep(dwTime);
    }
}

// If the function succeeds, the return value is nonzero.
unsigned long CThread::SetThreadAffinityMask(unsigned long dwThreadAffinityMask)
{// 暂未实现
    return 0;
}
bool CThread::StartThread(void (WINAPI *ThreadFun)(void* pParam),Priority nPriority,void* ThreadParam)
{
    FUN_ThreadFun = ThreadFun;
    m_lpThreadParam = ThreadParam;

    start(nPriority);
    return true;
}
//设置优先级为高于正常
bool CThread::SetThreadPriority(Priority priority)
{
    setPriority(priority);
    return false;
}
unsigned long CThread::ResumeThread()
{// 暂未实现
    return 0xFFFFFFFF;
}
unsigned long CThread::SuspendThread()
{// 暂未实现
    return 0xFFFFFFFF;
}

// 强制杀掉线程
bool CThread::TerminateThread()
{
    terminate();

    return true;
}
//使用

 static void WINAPI Thread_Fun(void* wParam);

void CTest::Start()
{
  CThread *pThead = new CThread ;
   pThead ->SetCustomData(this);
   pThead ->SetTimOut(2000);
   pThead ->StartThread(Thread_Fun,CThread::NormalPriority,pThead );
} 

void WINAPI CTest::Thread_Fun(void* wParam)
{
  CThread *pThread = (CThread*)wParam;
  if(pThread)
  {
    CTest*pFrame = (CTest*)pThread->GetCustomData();
    if(pFrame)
    {
      while(!pThread->IsQuit())
      {
        // 处理指令函数
        pThread->ThreadSleep(1);
      }
    }
  }
}
时间: 2024-10-20 06:58:17

QThead实现模拟VC线程函数的相关文章

【转】VC 线程间通信的三种方式

原文网址:http://my.oschina.net/laopiao/blog/94728 1.使用全局变量(窗体不适用)      实现线程间通信的方法有很多,常用的主要是通过全局变量.自定义消息和事件对象等来实现的.其中又以对全局变量的使用最为简洁.该方法将全局变量作为线程监视的对象,并通过在主线程对此变量值的改变而实现对子线程的控制.      由于这里的全局变量需要在使用它的线程之外对其值进行改变,这就需要通过volatile关键字对此变量进行说明.使用全局变量进行线程通信的方法非常简单

C语言::模拟实现strlen函数

编写一个C语言程序模拟实现strlen函数. 算法 strlen函数功能是计算字符串中字符的个数.(除\0外) 而字符串本身就是一个字符数组,只不过末尾以\0结束. 因此,我们只需遍历除\0之外的所有字符即可. 有三种方法可以解决这个问题. 算法总结 方法一:设置一个整型计数器,遍历字符串. 方法二:通过不断函数自身的递归. 方法三:与方法一类似,设置一个char*变量标记字符串尾部,通过指针相减得到字符长度. 核心代码 //方法一:通过设置整型计数器,模拟实现strlen函数. int my_

C语言::模拟实现strcmp函数

题目要求 编写一个C语言程序模拟实现strcmp函数. (我们依然先模拟实现strcmp函数,然后再对照string.h库中strcmp函数的实现,对比与大师之间的差距.) 算法分析 通过上一篇文章:C语言::strcmp函数功能.原型.用法及实例我们获得了strcmp函数的如下信息: strcmp原型:int strcmp( const char *s1, const char *s2 ); strcmp功能:将两个字符串自左向右逐个字符进行相比(根据ASCII值大小),直到出现不同的字符或遇

C语言::模拟实现strcat函数

题目要求 编写一个C语言程序模拟实现strcat函数. (我们不妨先模拟实现一下strcat函数,然后再对照一下string.h库函数中strcat函数代码的实现,与大师肩并肩.) 算法分析 strcat函数功能:将两个字符串连接起来,最终返回连接后字符串的首地址. strcat函数原型:char *strcat(char *dest,const char *src); 我们清楚地了解了strcat函数功能和原型之后,就很容易分析出算法... 算法总结 第一步:将dest指向的内容循环遍历至'\

【C语言】模拟实现atoi函数

atoi(表示 ascii to integer)是把字符串转换成整型数的一个函数. atoi()函数会扫描参数 nptr字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过isspace( )函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回.如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回0 我们在模拟实现atoi函数时,要注意以下几点: 1.字符串之前的空白问题 2.正负号 3.字符串为空时 4.

线程函数问题

If you are rusty on your C++, let me remind you of the problem. Every C++ member function has a hidden first passed parameter known as the this parameter.Via the this parameter, the function knows which instance of the class to operate upon. Because

为什么类中的线程函数必须要声明静态

其实类的静态函数就跟全局函数是一个样子的, 只是调用的时候要加下个类修饰符而已. 至于为什么不能是非静态成员函数呢, 因为非静态成员函数都会在参数列表中加上一个this指针为为参数, 这样的话你写的线程函数就不符合调用规定了.比如 DWORD WINAPI ThreadFun(LPVOID); 是非静态的,实际编译后,就会变成DWORD WINAPI ThreadFun(LPVOID, CMyClass *this); 这个函数就明显不能作为线程的函数了, 因为多了个参数.所以编译就过不了了.

管理线程之向线程函数传递參数

向线程函数传递參数在构造线程对象时就可以完毕.可是要记住,默认情况下是把參数复制到线程内部,即使在函数中使用的是引用.比如 void f(int i,std::string const &s); std::thread t(f,3,"hello"); 上面代码中,函数f的第二个參数是std::string,传递的是char const *会转换为string. 当使用指针指向自己主动变量时.要特别注意: void f(int i, std::string const&

【C语言】模拟实现memmove函数(考虑内存重叠)

//模拟实现memmove函数(考虑内存重叠) #include <stdio.h> #include <assert.h> #include <string.h> void * memmove(void * dst, const void * src, int count) { void * ret = dst; assert(dst); assert(src); if (dst <= src || (char *)dst >= ((char *)src