前人總結出,乙個執行緒安全的class應當滿足的條件:
1. 從多個執行緒訪問時,其表現出正確的行為,無論作業系統如何排程這些執行緒,無論這些執行緒的執行順序如何交織。
2. 呼叫端**無需額外的同步或其他協調動作
在寫多執行緒程式時腦子裡要有這樣的意識,下面我總結了幾條比較具體的注意事項。
使用多執行緒要考慮的問題:
1. 執行緒訪問資源安全(執行緒同步問題),這個問題,可用mutex封裝臨界區,我的另一篇blog裡有介紹.
2. 執行緒退出安全(主線程結束前線程安全退出),可在主線程結束時,在物件析構裡等待執行緒退出再析構.
3. 跨執行緒使用的物件的生命週期的控制,要保證物件(指標)不再被使用時才析構。為了安全,少費精力,還是用shared_ptr代替原始指標吧。shared_ptr是boost庫的智慧型指標,現在已加入標準庫中,用法不說了,說一下執行緒中使用注意事項吧。
shared_ptr的執行緒安全:
shared_ptr的執行緒安全級別與內建型別一樣,多個執行緒同時對乙個shared_ptr進行讀操作時是安全的,多個執行緒同時對多個shared_ptr進行寫操作時是安全的,其餘都是未定義的。
shared_ptr作為函式引數:
因為拷貝shared_ptr是要修改引用計數的,所以拷貝shared_ptr比拷貝原始指標成本要高,多數情況下可以以reference to const方式傳遞,只需要在最外層的函式有個實體物件,以後都可以用reference to const來使用這個shared_ptr。
下面我寫了個執行緒封裝類(windows平台),執行緒時使用它能少寫一些**~ 原始碼呈上:
#ifndef hbase_hthread_h__
#define hbase_hthread_h__
#include #ifdef ***_callback
#include #endif
/** 在類a中使用hthread類:
* 將hthread類的物件作為類a的成員.
* start函式,啟動乙個執行緒
* waitexit函式,在a的析構裡呼叫,保證在主線程退出前線程退出.
* 注意:乙個hthread類同時最多只能執行乙個執行緒。
* 如果使用callback封裝unsigned (__stdcall * _start_address) (void *)函式,使用更靈活.
*/class hthread
handle gethandle() const
protected:
#ifdef ***_callback
static unsigned __stdcall threadruntime(void* p);
#endif
private:
hthread(const hthread&);
hthread& operator=(const hthread&);
private:
handle handle_;
};#endif
#include #include "hthread.h"
hthread::hthread() : handle_(null)
{}hthread::~hthread()
#ifdef ***_callback
unsigned __stdcall hthread::threadruntime(void* p)
bool hthread::start(***::callback _cb)
#endif
bool hthread::start(unsigned (__stdcall * _start_address) (void *), void * _arg_list)
int hthread::waitexit()
detach();
return out;
}bool hthread::isrunning()
void hthread::detach()
}
在用執行緒處理問題時常常分兩種情況:
a. 這個執行緒只做一件事,或迴圈做一件事情,做完這件事情之後就不再用它了,此時就要結束這個執行緒,稱這種執行緒為單任務型。
單任務型適合用於耗時的重複性操作,比如上傳1000張,這種執行緒為該任務而生,任務結束執行緒也就結束了。
說了這麼多,看**吧~
#ifndef material_thread_h__
#define material_thread_h__
#include #include #include class taskthreadbase
handle gethandle() const
private:
taskthreadbase(const taskthreadbase&);
taskthreadbase& operator=(const taskthreadbase&);
protected:
handle handle_;
bool running_;
};class taskthread : public taskthreadbase
;class mutitaskthread : public taskthreadbase
task(upp::callback cb) : cb(cb) {}
upp::callback cb;
};public:
mutitaskthread();
~mutitaskthread();
void setmaxtaskcount(size_t task_count);
bool start();
bool addtask(upp::callback cb, bool priority = false);
virtual int waitexit();
private:
static unsigned __stdcall threadruntime(void* p);
void run();
void dotask(const task& task);
void requeststop();
private:
std::dequetasks_;
size_t max_task_count_;
upp::mutex mutex_;
upp::semaphore semaphore_;
bool quit_;
};#endif
#include #include "materialthread.h"
taskthreadbase::taskthreadbase() : handle_(null)
{}taskthreadbase::~taskthreadbase()
int taskthreadbase::waitexit()
detach();
return out;
}bool taskthreadbase::isrunning()
void taskthreadbase::detach()
}taskthread::taskthread()
taskthread::~taskthread()
unsigned __stdcall taskthread::threadruntime(void* p)
bool taskthread::start(upp::callback _cb)
bool taskthread::start(unsigned (__stdcall * _start_address) (void *), void * _arg_list)
mutitaskthread::mutitaskthread() : max_task_count_(1), quit_(false)
mutitaskthread::~mutitaskthread()
void mutitaskthread::setmaxtaskcount(size_t task_count)
bool mutitaskthread::start()
unsigned __stdcall mutitaskthread::threadruntime(void* p)
void mutitaskthread::requeststop()
void mutitaskthread::run()
if (quit_) break;
if (!empty)
}else
semaphore_.wait();
} running_ = false;
}bool mutitaskthread::addtask(upp::callback cb, bool priority /*= false*/)
return ret;
}void mutitaskthread::dotask(const task& task)
int mutitaskthread::waitexit()
(完)
多執行緒程式設計之執行緒的封裝
前人總結出,乙個執行緒安全的class應當滿足的條件 1.從多個執行緒訪問時,其表現出正確的行為,無論作業系統如何排程這些執行緒,無論這些執行緒的執行順序如何交織。2.呼叫端 無需額外的同步或其他協調動作 在寫多執行緒程式時腦子裡要有這樣的意識,下面我總結了幾條比較具體的注意事項。使用多執行緒要考慮...
多執行緒程式設計之執行緒取消
關鍵 pthread cancel函式傳送 終止訊號 pthread setcancelstate函式 設定終止方式 pthread testcancel函式取消執行緒 另一功能是 設定取消點 1 執行緒取消的定義 一般情況下,執行緒在其主體函式退出的時候會自動終止,但同時也可以因為接收到另乙個執行...
多執行緒程式設計之執行緒死鎖問題
在多執行緒程式設計中,除了要解決資料訪問的同步與互斥之外,還需要解決的重要問題就是多執行緒的死鎖問題。所謂死鎖 是指兩個或兩個以上的程序 執行緒 在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外部處理作用,它們都將無限等待下去。一 死鎖原因與形成條件 死鎖形成的原因 系統資源不足 程序 執...