分享

C++ 中怎样在一个类对象中使用多线程

 禁忌石 2017-06-05
我是在一个类中定义两个函数,然后在main函数中创建两个线程,而线程的两个操作就是那个类对象的两个函数。发现不管怎么样都是错误。错误代码为“函数调用缺少参数列表,请使用XXX创建指向成员的指针。”

C/C++ code

#include <Windows.h>
 
class Object
{
    DWORD WINAPI fun1(LPVOID lpParam);
    DWORD WINAPI fun2(LPVOID lpParam);
};
 
DWORD WINAPI Object::fun1(LPVOID lpParam)
{
    // do something
    return 0;
}
 
DWORD WINPAI Object::fun2(LPVOID lpParam)
{
    // do something
    return 0;
}
 
int main()
{
    Object o;
    HANDLE hThread1 = CreateThread(NULL, 0, o.fun1(), NULL, 0, NULL);
    HANDLE hThread2 = CreateThread(NULL, 0, o.fun2(), NULL, 0, NULL);
    // HANDLE hThread1 = CreateThread(NULL, 0, o.fun1, NULL, 0, NULL); 这样写也不对
    while(true)
    {
        Sleep(100);
    }
    return 0;
}

****************************************************************************
(对CreateThread来说,)作为线程函数的函数如果是类成员,则必须为静态成员。
将线程传入的函数设为static,网上还有一种解决方法,具体忘了,有兴趣可以查查

******************************************************************************
一般来说是使用一个公共的线程入口,再通过lpParameter参数来做具体的工作,比如:
C/C++ code

#include <Windows.h>
 
#include <functional>
 
DWORD WINAPI ThreadDummy(LPVOID pCallable)
{
    auto fun = static_cast<std::function<DWORD(void)>*>(pCallable);
    DWORD ret = (*fun)();
    delete fun;
    return ret;
}
 
struct Object
{
    DWORD WINAPI fun1();
    DWORD WINAPI fun2();
};
  
DWORD WINAPI Object::fun1()
{
    // do something
    return 0;
}
  
DWORD WINAPI Object::fun2()
{
    // do something
    return 0;
}
  
int main()
{
    Object o;
    HANDLE hThread1 = CreateThread(NULL, 0, ThreadDummy, new std::function<DWORD(void)>(std::bind(&Object::fun1, &o)), 0, NULL);
    HANDLE hThread2 = CreateThread(NULL, 0, ThreadDummy, new std::function<DWORD(void)>(std::bind(&Object::fun2, &o)), 0, NULL);
    while(true)
    {
        Sleep(100);
    }
    return 0;
}

***************************************************************
直接用类的成员函数绑定即可。前提是得启用c++11的std::thread
****************************************************************
一般来说是使用一个公共的线程入口,再通过lpParameter参数来做具体的工作,比如:
C/C++ code

#include <Windows.h>
 
#include <functional>
 
DWORD WINAPI ThreadDummy(LPVOID pCallable)
{
    auto fun = static_cast<std::function<DWORD(void)>*>(pCallable);
    DWORD ret = (*fun)();
    delete fun;
    return ret;
}
 
struct Object
{
    DWORD WINAPI fun1();
    DWORD WINAPI fun2();
};
  
DWORD WINAPI Object::fun1()
{
    // do something
    return 0;
}
  
DWORD WINAPI Object::fun2()
{
    // do something
    return 0;
}
  
int main()
{
    Object o;
    HANDLE hThread1 = CreateThread(NULL, 0, ThreadDummy, new std::function<DWORD(void)>(std::bind(&Object::fun1, &o)), 0, NULL);
    HANDLE hThread2 = CreateThread(NULL, 0, ThreadDummy, new std::function<DWORD(void)>(std::bind(&Object::fun2, &o)), 0, NULL);
    while(true)
    {
        Sleep(100);
    }
    return 0;
}
**************************************************************************************************

一般来说是使用一个公共的线程入口,再通过lpParameter参数来做具体的工作,比如:
C/C++ code

#include <Windows.h>
 
#include <functional>
 
DWORD WINAPI ThreadDummy(LPVOID pCallable)
{
    auto fun = static_cast<std::function<DWORD(void)>*>(pCallable);
    DWORD ret = (*fun)();
    delete fun;
    return ret;
}
 
struct Object
{
    DWORD WINAPI fun1();
    DWORD WINAPI fun2();
};
  
DWORD WINAPI Object::fun1()
{
    // do something
    return 0;
}
  
DWORD WINAPI Object::fun2()
{
    // do something
    return 0;
}
  
int main()
{
    Object o;
    HANDLE hThread1 = CreateThread(NULL, 0, ThreadDummy, new std::function<DWORD(void)>(std::bind(&Object::fun1, &o)), 0, NULL);
    HANDLE hThread2 = CreateThread(NULL, 0, ThreadDummy, new std::function<DWORD(void)>(std::bind(&Object::fun2, &o)), 0, NULL);
    while(true)
    {
        Sleep(100);
    }
    return 0;
}
谢谢 ,非常感谢! 我想问个问题,如果说一个类中有成员变量,这个会影响吗?

************************************************************************************
不会。如果你有条件使用C++11编译器,也可以使用std::thread,基本思路都是一样的

****************************************************************************************
使用类的静态成员函数作为线程的过程函数,这样避免了对象的this指针问题

************************************************************************************

CreateThread的线程入口函数不能是一个类成员函数。不过可以使用std::thread实现,需要VS2012或以上的编译器支持
C/C++ code

#include <thread>
#include <iostream>
using namespace std;
 
class MyClass
{
public:
    MyClass(int n) : m_n(n){}
    void Run()
    {
        cout << m_n << endl;
    }
    int m_n;
};
 
 void main()
 {
     MyClass test(5);
     thread th(&MyClass::Run, &test);
     th.join();
 }

************************************************************************************
使用类的静态成员函数作为线程的过程函数,这样避免了对象的this指针问题
我也了解过了,可是我设计的那个东西,必须要和对象有关联。也就是说一个对象必须要运行几个线程。
*************************************************************************************

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多