同步 c++11 lock_guard is no longer recommended.
c++ 17 unique_lock and scoped_lock are recommended.
unique_lock 和 lock_guard 类似,增加一些有用的函数。 unique_lock can unlock, not lock_guard
std::mutex m_mutex_write; std::unique_lock guard (m_mutex_write) ;guard.unlock (); guard.lock ();
wait event win32
Condition Variables
临界区本身不是内核对象,它是工作在用户态的,所以速度快一些 互斥量、信号量、事件都是Windows的内核对象,当程序对这些对象进行控制时会自动转换到核心态。
C++ 方式 mutable std::mutex mutMapInst;{ std::lock_guard<std::mutex>lk (m_devInfo.mutMapInst); m_devInfo.mapInst.emplace (make_pair (instId, &dev)); }
MFC 方式 CMutex Mutex; CSingleLock SingleLock (&Mutex) ;SingleLock.Lock ();
Win32 方式 CRITICAL_SECTION cs; InitializeCriticalSection (&m_curInfo.cs);EnterCriticalSection (&m_curInfo.cs);m_curInfo.timeCmp = time (NULL ); LeaveCriticalSection (&m_curInfo.cs);DeleteCriticalSection (&m_curInfo.cs);
同步事件 HANDLE m_hEvent_write; m_hEvent_write = CreateEvent ( NULL , TRUE, FALSE, TEXT ("WriteEvent" ) ); WaitForSingleObject (pwnd->m_hEvent_write, INFINITE);::SetEvent (m_hEvent_write); CloseHandle (m_hEvent_write)
指针参数 可以使用智能指针保存参数,然后传给工作线程。 目前还没找到更好的办法,只能复制一份给工作线程使用。
int CserialPort::write (const BYTE* data, const DWORD& length) { std::shared_ptr<BYTE[]> spBuf (new BYTE[length]) ; memcpy (spBuf.get (), data, length); std::thread threadWork = std::thread (threadWrite, this , spBuf,length); threadWork.detach (); return 0 ; }
C++ 14 注意:可被 joinable 的 std::thread 对象必须在他们销毁之前被主线程 join 或者将其设置为 detached.
if (false == m_thread_recive.joinable ()){ m_thread_recive = std::thread (threadReceive, this ); } int threadReceive (const void * p) { CTcpClient* pwnd = (CTcpClient*)p; while (FLAG_EXIT_THREAD_RECEIVE != (pwnd->m_flag&FLAG_EXIT_THREAD_RECEIVE)) { for (int i = 0 ; i < 20 ; ++i) { if (FLAG_EXIT_THREAD_RECEIVE == (pwnd->m_flag&FLAG_EXIT_THREAD_RECEIVE)) { goto skip_return; } this_thread::sleep_for (chrono::milliseconds (100 )); } } skip_return: return 0 ; }
std::thread th (&Task::execute, taskPtr, "Sample Task" ) ;
std::thread m_threadHttpServer; if (FLAG_HTTP_SERVER_RUNNING != (g_iFlag&FLAG_HTTP_SERVER_RUNNING)){ m_threadHttpServer = std::thread (threadHttpServer, (this ), 2 ,"other param" ); } g_iFlag |= FLAG_EXIT_HTTP_SERVER; while (FLAG_HTTP_SERVER_RUNNING == (g_iFlag&FLAG_HTTP_SERVER_RUNNING)){ Sleep (200 ); } if (m_threadHttpServer.joinable ()){ m_threadHttpServer.join (); } g_iFlag &= (~FLAG_EXIT_HTTP_SERVER);
ref.
A thread can be created in several ways:
Using a function pointer
Using a functor
Using a lambda function
对于判断线程是否执行完毕,可以通过自己设置 flag 来判断.
#include <iostream> #include <thread> str.Format (L"foo %d\n" , i); OutputDebugString (str); Sleep (1000 ); } } void bar (int & x, int & out) { int m = 0 ; CString str; for (int i = 0 ; i < 5 ; ++i) { m += x; str.Format (L"bar %d\n" , i); OutputDebugString (str); Sleep (1000 ); } out = m; } int main () { CString str; std::thread first (foo) ; int out = 0 ; int in = 10 ; std::thread second (bar, ref(in),ref(out)) ; OutputDebugString (L"main, foo and bar now execute concurrently...\n" ); first.join (); second.join (); str.Format (L"foo and bar completed. out:%d\n" , out); OutputDebugString (str); return 0 ; }
std::ref 主要是考虑函数式编程(如std::bind)在使用时,是对参数直接拷贝,而不是引用。
warning: all parameters is passing default by value unless you wrap them in std::ref.
C run-time libraries _beginthread or _beginthreadex
结束线程 _endthread _endthread automatically closes the thread handle.