大纲:
零。关于同步与互斥的多线程编程(一般思路)
1. 申请“信号量”句柄,初始化信号量。 (HANDLE ...)
2. 创建使用上线程的函数(函数中需要用到信号量)。(CreateSemaphore(...))
3. 创建线程(创建线程时用上第二步的函数)。(CreateThread(...))
4. 等待结束线程。(WaitForSingleObject(...))
5. 关闭句柄。(CloseHandle(...))
一。放水果问题
1. 程序演示
2. 程序运行效果
3. 运行结果简要分析
二。生产者与消费者问题
1. 程序演示
2. 程序运行效果
3. 运行结果简要分析
内容:
一。放水果问题
1. 程序演示
-
-
-
-
-
-
-
-
-
-
-
- #include <iostream>
- #include <windows.h>
-
- using namespace std;
-
-
- HANDLE emptyMutex;
- HANDLE orangeMutex;
- HANDLE fruitMutex;
-
- int main()
- {
-
-
- emptyMutex = CreateSemaphore(NULL, 1, 1, NULL);
- orangeMutex = CreateSemaphore(NULL, 0, 1, NULL);
- fruitMutex = CreateSemaphore(NULL, 0, 1, NULL);
-
-
- DWORD WINAPI fatherThread(LPVOID IpParameter);
- DWORD WINAPI motherThread(LPVOID IpParameter);
- DWORD WINAPI sonThread(LPVOID IpParameter);
- DWORD WINAPI daughterThread(LPVOID IpParameter);
-
-
- cout << "盘子取放水果游戏开始." << endl;
-
-
- HANDLE fThread = CreateThread(NULL, 0, fatherThread, NULL, 0, NULL);
- HANDLE mThread = CreateThread(NULL, 0, motherThread, NULL, 0, NULL);
- HANDLE sThread = CreateThread(NULL, 0, sonThread, NULL, 0, NULL);
- HANDLE dThread = CreateThread(NULL, 0, daughterThread, NULL, 0, NULL);
-
-
- WaitForSingleObject(fThread, INFINITE);
- WaitForSingleObject(mThread, INFINITE);
- WaitForSingleObject(sThread, INFINITE);
- WaitForSingleObject(dThread, INFINITE);
-
-
- CloseHandle(fThread);
- CloseHandle(mThread);
- CloseHandle(sThread);
- CloseHandle(dThread);
-
- CloseHandle(emptyMutex);
- CloseHandle(orangeMutex);
- CloseHandle(fruitMutex);
-
- cout << "\n盘子取放水果游戏结束." << endl;
- system("pause");
- return 0;
- }
-
- DWORD WINAPI fatherThread(LPVOID IpParameter)
- {
- for(int i = 0; i < 5; ++i){
- WaitForSingleObject(emptyMutex, INFINITE);
-
- cout << "\nFather往盘中放一个苹果\n";
-
- ReleaseSemaphore(fruitMutex, 1, NULL);
- }
- return 0;
- }
-
- DWORD WINAPI motherThread(LPVOID IpParmeter)
- {
- for(int i = 0; i < 5; ++i){
- WaitForSingleObject(emptyMutex, INFINITE);
-
- cout << "\nMother往盘中放一个桔子\n";
-
- ReleaseSemaphore(orangeMutex, 1, NULL);
- }
- return 0;
- }
-
- DWORD WINAPI sonThread(LPVOID IpParmeter)
- {
- for(int i = 0; i < 5; ++i){
- WaitForSingleObject(orangeMutex, INFINITE);
-
- cout << "Son往盘中取一个桔子\n";
-
- ReleaseSemaphore(emptyMutex, 1, NULL);
- }
- return 0;
- }
-
- DWORD WINAPI daughterThread(LPVOID IpParmeter)
- {
- for(int i = 0; i < 5; ++i){
- WaitForSingleObject(fruitMutex, INFINITE);
-
- cout << "Daughter往盘中取一个苹果\n";
-
- ReleaseSemaphore(emptyMutex, 1, NULL);
- }
- return 0;
- }
2. 程序运行效果

3. 运行结果简要分析
首先由结果可以看见的是,它们已经按题目要求输出了,Father放入的是苹果,Mother放入的是Orange,而Son取的是Orange,Daughter取的是苹果,这里一共有十次的放入操作,分别是五次父亲的放入及五次母亲的放入,还有十次的取出操作,分别是女儿的取出还有儿子的取出,而这些放入与取出,都遵循着这么一个规律,“取”建立在“放”之前,而且必是一放一取,也就是满足了题目要求中的盘子一次只能有一个水果的要求。
二。生产者与消费者问题
1. 程序演示
-
-
-
-
-
-
-
-
-
-
-
- #include <iostream>
- #include <string.h>
- #include <windows.h>
-
- using namespace std;
-
-
- HANDLE emptyMutex;
- HANDLE fullMutex;
- HANDLE bufferMutex;
-
-
- char buffer[] = "123456";
- const int maxBufferNumber = strlen(buffer) - 1;
- int nowUsingBufferNumber(0);
-
- int main()
- {
-
-
- emptyMutex = CreateSemaphore(NULL, maxBufferNumber, maxBufferNumber, NULL);
- fullMutex = CreateSemaphore(NULL, 0, maxBufferNumber, NULL);
- bufferMutex = CreateSemaphore(NULL, 1, 1, NULL);
-
-
- DWORD WINAPI ProducerThread(LPVOID IpParameter);
- DWORD WINAPI ConsumerThread(LPVOID IpParameter);
-
- cout << "-> 生产者、消费者问题开始.\n" << endl;
-
-
- HANDLE pThread = CreateThread(NULL, 0, ProducerThread, NULL, 0, NULL);
- HANDLE cThread = CreateThread(NULL, 0, ConsumerThread, NULL, 0, NULL);
-
-
- WaitForSingleObject(pThread, INFINITE);
- WaitForSingleObject(cThread, INFINITE);
-
-
- CloseHandle(pThread);
- CloseHandle(cThread);
-
- CloseHandle(emptyMutex);
- CloseHandle(fullMutex);
- CloseHandle(bufferMutex);
-
- cout << "\n-> 生产者、消费者问题结束." << endl;
- system("pause");
- return 0;
- }
-
-
-
- DWORD WINAPI ProducerThread(LPVOID IpParmeter)
- {
- int n = 10;
- while(n--){
- WaitForSingleObject(emptyMutex, INFINITE);
-
- WaitForSingleObject(bufferMutex, INFINITE);
- nowUsingBufferNumber = (nowUsingBufferNumber + 1) % maxBufferNumber;
- buffer[nowUsingBufferNumber] = nowUsingBufferNumber + 'A';
- cout << "Hey, 生产者正在为你放入第" << nowUsingBufferNumber << "个资源"
- << ",资源的内容为" << buffer[nowUsingBufferNumber]
- << " ( put put put .... )" << endl;
- ReleaseSemaphore(bufferMutex, 1, NULL);
-
- ReleaseSemaphore(fullMutex, 1, NULL);
- }
- return 0;
- }
-
- DWORD WINAPI ConsumerThread(LPVOID IpParameter)
- {
- int n = 10;
- while(n--){
- WaitForSingleObject(fullMutex, INFINITE);
-
- WaitForSingleObject(bufferMutex, INFINITE);
- cout << "Yoo, 消费者正在取出第" << nowUsingBufferNumber << "个资源"
- << ",资源的内容为" << buffer[nowUsingBufferNumber]
- << " (get...)" << endl;
- nowUsingBufferNumber = (nowUsingBufferNumber - 1 + maxBufferNumber) % maxBufferNumber;
- ReleaseSemaphore(bufferMutex, 1, NULL);
-
- ReleaseSemaphore(emptyMutex, 1, NULL);
- }
- return 0;
- }
2. 程序运行效果

3. 运行结果简要分析
可以看见的是,这里共执行了十次的生产者放入资源操作与十次的消费者取出资源的操作,在缓冲池有数据的时候,消费者可以从缓冲区取出资源,刚刚开始时,生产者先放入资源“B”,由于缓冲区未满,所以生产者仍可继续再放入资源“C”,这时,虽然生产者可以继续放入资源,但是,由于消费者线程先执行操作了,从缓冲区中取出资源,所以,生产者的放入资源操作会在消费者的取出操作完成后再进行,按照生产者缓冲区有非满且非在进行操作则可放,消费者缓冲区非空且非在进行操作则可取的原则,这两个进行不断地运行循环,直到完成循环中设定的次数,最后,由于程序中的生产者与消费者的操作数目设定相同,所以,到最后会将缓冲区清空后退出程序。
http://blog.youkuaiyun.com/neicole/article/details/7459000