最近在寫個專案,比如有一個類的成員函式,這個成員函式會做一些很重的事情 比如一個HTTP請求。我在執行緒A里面呼叫這個
成員函式不現實,想將這個成員函式分派到一個執行緒里面去跑。有什么優雅的方法么?
比如
class ClassA obj;
obj.fun() //這個fun就是HTTP請求或者其他一些很重的事情要執行幾秒。我想把這個放到執行緒里面去執行。
我自己現在用的方法不好看。比如有個執行緒池 有一個執行緒是空閑的。我在類里面定義了一個成員static函式
static int threadFun(ClassA *self)
{
self->fun();
}
這樣來執行的。封裝性不好 。比如我要執行fun2() 又要單獨去寫個threadFun2 。很丑 。
有誰有更好的辦法嗎?
本來想用匯編代碼把this指標給ecx然后call。也不靠譜 不同編譯器的thiscall的呼叫約定也不太一樣。在C++層面是否有方法可以做到?
uj5u.com熱心網友回復:
可以考慮用類函式指標uj5u.com熱心網友回復:
都想到匯編直接用ecx賦值了,類函式指標傳遞,或者把執行緒引數弄個結構,把需要的指標都傳進去。uj5u.com熱心網友回復:
function 還是要一個一個寫,fubctions 搞成 一個 陣列,
類里 搞個 index m_funidx
static int threadFun(ClassA *self)
{
self->funs[m_funidx];
}
uj5u.com熱心網友回復:
你可以定義一些回呼函式,將這些回呼函式和相關的CONTEXT背景關系引數封裝一下,作為執行緒函式的引數傳遞給執行緒。uj5u.com熱心網友回復:
static int threadFun(){
ClassA *self = new ClassA();
self->fun();
}
這樣定是不是封裝性好?
uj5u.com熱心網友回復:
class IRunnable
{
public:
virtual void Run() = 0;
};
class CThread
{
public:
CThread(IRunnable * run);
~CThread();
public:
void Start();
void WaitFinish();
public:
IRunnable* m_run = NULL;
HANDLE m_hThread = NULL;
};
樓主有了解回呼和虛函式嗎?
有的話,上面的介面就可以辦到說的。
uj5u.com熱心網友回復:
#include "stdafx.h"
#include "Thread.h"
CThread::CThread(IRunnable * run)
{
m_run = run;
}
CThread::~CThread()
{
::CloseHandle(m_hThread);
}
static DWORD WINAPI ThreadFunc(LPVOID param)
{
CThread* thread = (CThread*)param;
if (thread->m_run != NULL)
{
thread->m_run->Run();
}
return 0;
}
void CThread::Start()
{
if (m_hThread == NULL)
{
DWORD dwThreadID = 0;
m_hThread = ::CreateThread(NULL, 0, ThreadFunc, this, 0, &dwThreadID);
}
}
void CThread::WaitFinish()
{
::WaitForSingleObject(m_hThread, INFINITE);
}
uj5u.com熱心網友回復:
https://blog.csdn.net/xuan_xuan_2/article/details/89299048參考下QThreadPool、和QRunnable 的實作辦法,
其實這種在java里是很常見的設計模式。。。
uj5u.com熱心網友回復:
還沒結帖吧?封裝一個list,每次遇到請求都塞到這個list里面
執行緒里面如下
while(1)
{
if(threadover)
break;
int res = waitforsingleobject(newmsgevent,,waittime) ;
根據res判斷如果不是object_0
那么在newmsg沒有被其他地方銷毀的情況下
可能是超時了,否則直接break結束執行緒
resetevent(newmsgevent);
// 先到先處理
ClassA *self = list.getmsg();
list.remove(slef);
self.dosomething();
list為空時,直接卡死等新的資訊來
waittime = -1;
if (list.isnotempty()){
// 否則直接超時回傳。接著處理
waittime=0;
}
怕資料量多cpu高可以sleep一下。正常情況下感覺沒必要。根據實際需求吧。
}
請求來的時候,做如下處理
ClassA *self = createnewrequest();
list.add(slef);
setevent(newmsgevent);
邏輯很簡單,執行緒好寫了吧。
需要注意的問題是list需要做執行緒互斥。否則多執行緒插入,洗掉會出錯。
其他事件句柄/全域變數的創建等都是小菜了。
uj5u.com熱心網友回復:
c++11的閉包可以輕易實作,甚至可以使用泛型執行緒池https://github.com/gdlxSong/GdlLib/tree/master/gdltool/threadpool另外,c++11提供標準庫執行緒庫,可以使用std::thread,
example:
class Test{
public:
void run(int){}
}
main(){
Test test;
std::thread th(&Test::run, &test, 20);
//...
th.join();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/26937.html
標籤:進程/線程/DLL
