Win32多线程编程练习

来源:互联网 发布:科学简史 知乎 编辑:程序博客网 时间:2024/04/29 18:21

练习一:

创建一个工作线程,主线程等待此线程返回后再继续执行(纯粹练习API用,无甚意义)。

因为线程间没有共享的资源,这里没有做多线程同步。如果工作线程里要使用 cout<<xx<<xxx... 需要实现多线程同步,因为控制台是标准输入输出设备,属独占资源。

#include <Windows.h>#include <iostream>#include <process.h>unsigned __stdcall SimpleThread(void* pParam){::Sleep(3000);return 0;}int main(){using namespace std;unsigned dwThreadID(0);HANDLE hThread = (HANDLE)::_beginthreadex(NULL, 0, SimpleThread, NULL, 0, &dwThreadID);if ( NULL == hThread ){cout<<"_beginthreadex failed. errno: "<<errno<<endl;return 1;}cout<<"_beginthreadex create new thread. handle: "<<hThread<<" id: "<<dwThreadID<<endl;::WaitForSingleObject(hThread, INFINITE);cout<<"The thread was signaled."<<endl;::CloseHandle(hThread);cin.get();return 0;}


练习二:

使用临界区对象(Critical Section Objects)实现多线程同步。

任一时刻只有一个线程可以拥有临界区对象,拥有临界区的线程可以访问被保护起来的资源或代码段,其他希望进入临界区的线程将被挂起等待,直到拥有临界区的线程放弃临界区时为止,这样就保证了不会在同一时刻出现多个线程访问共享资源。

#include <iostream>#include <Windows.h>#include <process.h>const int ARRAY_SIZE = 5;int g_IntArray[ARRAY_SIZE];CRITICAL_SECTION g_CriticalSection;void SimpleThread(void* pParam){int num(0);while (true){::EnterCriticalSection(&g_CriticalSection);for ( int i = 0; i < ARRAY_SIZE; ++i ){g_IntArray[i] = num;}::LeaveCriticalSection(&g_CriticalSection);num++;}}int main(){using namespace std;::InitializeCriticalSection(&g_CriticalSection);_beginthread(SimpleThread, 0, NULL);while (true){::EnterCriticalSection(&g_CriticalSection);for ( int i = 0; i < ARRAY_SIZE; ++i ){cout<<g_IntArray[i]<<" ";}::LeaveCriticalSection(&g_CriticalSection);cout<<endl;}return 0;}


练习三:

使用互斥对象(Mutex Objects)实现多线程同步。

互斥对象与临界区对象很像.互斥对象与临界区对象的不同在于:互斥对象可以在进程间使用,而临界区对象只能在同一进程的各线程间使用。当然,互斥对象也可以用于同一进程的各个线程间,但是在这种情况下,使用临界区会更节省系统资源,更有效率。

 

#include <iostream>#include <Windows.h>#include <process.h>const int ARRAY_SIZE = 5;int g_IntArray[ARRAY_SIZE];HANDLE g_hMutex;void SimpleThread(void* pParam){int num(0);while (true){::WaitForSingleObject(g_hMutex, INFINITE);for ( int i = 0; i < ARRAY_SIZE; ++i ){g_IntArray[i] = num;}::ReleaseMutex(g_hMutex);num++;}}int main(){using namespace std;g_hMutex = ::CreateMutex(NULL, FALSE, NULL);::_beginthread(SimpleThread, 0, NULL);while (true){::WaitForSingleObject(g_hMutex, INFINITE);for ( int i = 0; i < ARRAY_SIZE; ++i ){cout<<g_IntArray[i]<<" ";}::ReleaseMutex(g_hMutex);cout<<endl;}return 0;}


练习四:

使用事件通知(Event)实现多线程同步。

事件是一个允许一个线程在某种情况发生时,唤醒另外一个线程的同步对象。

 

#include <iostream>#include <Windows.h>#include <process.h>const int ARRAY_SIZE = 5;int g_IntArray[ARRAY_SIZE];HANDLE g_hEvent1, g_hEvent2;unsigned __stdcall SimpleThread(void* pParam){int count = (int)pParam;int num(0);while (count--){::WaitForSingleObject(g_hEvent1, INFINITE);for ( int i = 0; i < ARRAY_SIZE; ++i ){g_IntArray[i] = num;}::SetEvent(g_hEvent2);num++;}return 0;}int main(){using namespace std;g_hEvent1 = ::CreateEvent(NULL, FALSE, TRUE, NULL);g_hEvent2 = ::CreateEvent(NULL, FALSE, FALSE, NULL);int count(100);HANDLE hThread = (HANDLE)::_beginthreadex(NULL, 0, SimpleThread, &count, 0, NULL);if ( NULL == hThread ){cout<<"_beginthreadex failed. errno: "<<errno<<endl;return 1;}while (count--){::WaitForSingleObject(g_hEvent2, INFINITE);for ( int i = 0; i < ARRAY_SIZE; ++i ){cout<<g_IntArray[i]<<" ";}::SetEvent(g_hEvent1);cout<<endl;}// NOTE: The system closes the handle automatically when the process terminates.::CloseHandle(hThread);::CloseHandle(g_hEvent2);::CloseHandle(g_hEvent1);cin.get();return 0;}

 

另外,还有信号量对象(Semaphore)同步,因为目前项目中基本用不到没有做相应练习,等以后有空再补上。

本人的第一篇多线程文章,如果发现错误或不足的地方还忘不吝赐教,一旦发现错误将及时修正,以免误导大家。