將一般函式轉為執行緒執行

2021-04-01 05:22:03 字數 4559 閱讀 1176

//下面的**在vc6.0 sp6 下測試通過

#include "stdafx.h"

#pragma  warning (disable : 4786)

#include

#include

#include

using namespace std;

#include

#include

using namespace loki;

#include

namespace ext_loki

;template<>

struct paramholderimpl<1> ;

};template<>

struct paramholderimpl<2> ;};}

//可以根據typelist自動生成乙個結構並定義乙個結構成員和typelist中的型別對應

//如:

//paramholderlparam;  定義了乙個結構 並實現了乙個例項,並會有兩個 int p1; double p2 的結構成員

//這裡,我只定義了長度為2的typelist的實現,在具體的情況下,可以擴充需要的引數個數

template

struct paramholder : public ext_loki_private::paramholderimpl< tl::length<_tlist>::value >::template in<_tlist> ;

//定義可以提供執行緒啟動呼叫的介面

template

struct runimpl : public thread_call_func_prototype ;

template <>

struct runimpl<0>

template

in(_ret(*p)()) : implbase(p) {}

template <>

struct runimpl<1>

//模板函式,設定執行引數

template

void setparam(a1 p1)

template

in(_ret (*p)(a1)) : implbase(p) {}

template <>

struct runimpl<2>

template

void setparam(a1 p1,a2 p2)

template

in(_ret (*p)(a1,a2)) : implbase(p) {}

};};

//上面的**可以按照實際的需要擴充引數的數量

////定義乙個任務單元,可以作為函式子使用

template

class task_unit : public runimpl< tl::length<_tlist>::value >::template in<_ret,_tlist,_threadmode>

template

task_unit(_ret(*p)(a1)) : implbase(p) {}

template

task_unit(_ret(*p)(a1,a2)) : implbase(p) {}

~task_unit() {} 

};//上面的**擴充到了數量為2個引數

//對於原型為 void function_be_call(int value); 的函式可以這樣呼叫

// task_unitltask(function_be_call);

// ltask.setparam(100);

// ltask.run();

// 或者直接呼叫ltask(100); 也可以

//上面已經實現了函式子可以自己持有執行時候需要呼叫的引數

//並且由了統一的呼叫介面run()

//下面就定義執行緒執行的最終實現

//用模板方式實現了乙個執行緒管理器,或者可以叫執行緒池

namespace ext_loki

;//api實現的自定義互斥類,對於在不使用mfc的時候可以使用

class thread_mutex

return ret;

}bool unlock()

public:

thread_mutex()

~thread_mutex() }};

//自定義的執行緒鎖

template

class thread_lock

bool unlock()

public:

thread_lock(_locktype* value) : m_plocktype(value) {}

~thread_lock(){}

};//定義了乙個資料的 holder,可以對其中的資料進行執行緒安全的訪問

//如//mutex_access<__enum_thread__state,thread_mutex,thread_lock>

//mutex_access<__enum_thread__state,cmutex,csinglelock>  如果使用mfc

template

class mutex_access

_data operator*()

public:

mutex_access(){}

mutex_access(_data& value)

~mutex_access(){}

};//定義乙個傳入執行緒的統一引數結構

template

struct thread_param ;

//呼叫最終的呼叫函式,呼叫傳入的函式子

template

void thread_func_impl(actual_param* param)

//實現的乙個執行緒管理器

//class _functor    指定函式子介面

//class _size  指定最大的執行緒數量 使用int2type型別,可以指定執行緒數量

//class _thread_begin_func  指定啟動執行緒的函式的原型

//如window平台的 _beginthread  的原型是

//unsinged long (void(__cdecl*)(void*),unsigned,void*)

template

class thread_pool

}return ret;

}//**已經完成的任務引數,用於重新分配任務

void taskcollect()}}

//判斷是不是所有的執行任務是不是全部結束

bool taskover()

}return ret;

}public:

thread_pool(_thread_begin_func value,threadfuncimpl tf) : m_beginthreadfunc(value), m_pthreadfunc(tf)

}~thread_pool(){}

};#define thread_call_impl(e)  void thread_call_##e(void* param) /

}//下面的**開始測試將函式作為執行緒執行

//從 t0  到 t4 都為測試函式

//全域性互斥,防止螢幕字元輸出的時候發生混亂

ext_loki::thread_mutex gmutex;

void t0()

}void t1(int param)

}void t2(int v1,int v2)

}void t3(int v1, char c1)

}void t4(int* pint)

}//定義個執行緒管理器型別,最大執行執行緒數量為10

typedef ext_loki::thread_pool,unsigned long (*)(void(__cdecl *)( void * ),unsigned,void*)>  used_thread_pool;

//用巨集生成乙個全域性函式,作為執行緒啟動的入口點

thread_call_impl(used_thread_pool)

//測試函式

void test()

int main(int argc, char* argv)

由上面的**可以看到,儘管 t0 到 t4的函式,每個函式的原型都不同,需要輸入不同的執行引數,

但是通過模版的封裝,可以統一的放入同乙個執行緒池中執行,並且不需要建立額外的結構來傳輸引數,

對於將已有**轉換為執行緒執行,很方便,不需要編寫額外的的**,同時,如果要撤銷作為執行緒執行也方便.

//由於水平有限,上面的實現方式是由侷限性的,如對於

//函式引數為引用型別的函式是由問題的,

//所有的引數持有結構都是使用的預設建構函式,

//對於引用型別需要顯式的初始化,所以,對於

//象 void tt(int&) 型別的函式,會出現錯誤

//希望大家能討論一下,看看有沒有解決的方法.

//另外,boost中有的類也可以實現上述的功能,由於對boost不熟悉

//我不知道在boost中是如何解決 引用引數的問題和 多個引數的傳入問題的.

//水平有限,希望大家指正.

將一般的資料格式轉為libsvm格式

libsvm是台灣大學林智仁教授等研究人員開發的乙個用於支援向量機分類的c 開源庫,支援多種語言介面,並且可進行多分類與回歸問題的建模 在資料預處理階段,需要將資料集轉化為libsvm要求的格式 通常的原始資料集格式為 value1 value2 value3.label 而libsvm要求格式為 ...

建構函式和一般函式

建構函式 構建創造物件時呼叫的函式,作用 可以給物件進行初始化。建立物件都必須要通過建構函式初始化。如果乙個類中沒有定義建構函式,那麼該類中就會有乙個預設的無參建構函式。如果在類中定義了指定的建構函式,那麼類中的預設建構函式就沒有了。建構函式和一般函式有什麼區別呢?建構函式 物件建立時,就會呼叫與之...

python一般函式 python 函式

秋風蕭瑟 1.在乙個函式的命名空間中給乙個變數賦全域性的值,要把該變數賦為global a none def bind a variable global a a bind a variable print a 2.一般情況下函式返回多個物件時,會返回乙個tuple。但是也可以返回乙個dict,有時...