1. std::lock_guard
在c++11中的线程锁std::mutex
用于在代码的关键部分需要独占访问时发出信号,防止具有相同保护的其他线程同时执行并访问相同的内存位置。
在线程互斥代码块之前加锁
代码块结束后解锁
例子
// mutex example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
std::mutex mtx; // mutex for critical section
void print_block (int n, char c) {
// critical section (exclusive access to std::cout signaled by locking mtx):
mtx.lock();
for (int i=0; i<n; ++i) { std::cout << c; }
std::cout << '\n';
mtx.unlock();
}
int main ()
{
std::thread th1 (print_block,50,'*');
std::thread th2 (print_block,50,'$');
th1.join();
th2.join();
return 0;
}
使用std::lock_guard,它在构造时,互斥对象被调用线程锁定,在销毁时,互斥被解锁。
在它的构造函数中,调用互斥锁的lock函数,在他的析构函数中,调用互斥锁unlock函数
例子
// lock_guard example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::lock_guard
#include <stdexcept> // std::logic_error
std::mutex mtx;
void print_even (int x) {
if (x%2==0) std::cout << x << " is even\n";
else throw (std::logic_error("not even"));
}
void print_thread_id (int id) {
try {
// using a local lock_guard to lock mtx guarantees unlocking on destruction / exception:
std::lock_guard<std::mutex> lck (mtx);
print_even(id);
}
catch (std::logic_error&) {
std::cout << "[exception caught]\n";
}
}
int main ()
{
std::thread threads[10];
// spawn 10 threads:
for (int i=0; i<10; ++i)
threads[i] = std::thread(print_thread_id,i+1);
for (auto& th : threads) th.join();
return 0;
}
2. MFC类CPaintDC
在WIN32中响应窗体WM_PAINT消息:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// All painting occurs here, between BeginPaint and EndPaint.
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(hwnd, &ps);
}
...
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
其中BeginPaint 函数准备用于绘制的指定窗口,并使用有关绘图的信息填充 PAINTSTRUCT 结构。应用程序不应调用 BeginPaint ,除非响应 WM_PAINT 消息。 对 BeginPaint 的每个调用都必须具有对 EndPaint 函数的相应调用。
EndPaint 函数标记指定窗口中绘制的结尾。 每次调用 BeginPaint 函数时都需要此函数,但仅在绘制完成后才需要此函数。
MFC的OnPaint中CPaintDC dc(this)
CPaintDC
CPaintDC::CPaintDC 构造连接到指定的 CWnd 的 CPaintDC。
CPaintDC::m_ps 包含用于绘制工作区的 PAINTSTRUCT。
CPaintDC::m_hWnd 附加此 CPaintDC 对象的 HWND。
在构造时执行 CWnd::BeginPaint,在销毁时执行 CWnd::EndPaint。
传递给 CWnd::BeginPaint 并由其填充的是 PAINTSTRUCT。
使用:
3. 在堆栈中对象的区别
在堆中分配的对象,生命周期由程序员控制,需要手动释放内存,并且容易造成内存泄漏。
在栈中的对象,效率很高,但是分配的内存量有限,并且在作用域结束后就会销毁。在对象的析构函数中实现代码,实现在作用域结束执行的操作。