// MultiThread.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <process.h>
using namespace std;
CRITICAL_SECTION g_csA;
CRITICAL_SECTION g_csB;
UINT WINAPI PrintThread1(LPVOID lp)
{
while (1)
{
//该代码段最后看,用信号量实现10个线程同步有序
//if (WaitForSingleObject(g_hDemaphore, INFINITE) != WAIT_OBJECT_0)
//{
//continue;
//}
//
EnterCriticalSection(&g_csA);
for (int i=0;i<3;i++)
{
printf("thread1\n");
Sleep(1000);
}
printf("\n");
LeaveCriticalSection(&g_csA);
}
return 0;
}
UINT WINAPI PrintThread2(LPVOID lp)
{
while (1)
{
EnterCriticalSection(&g_csA);
for (int i=0;i<3;i++)
{
printf("thread2\n");
Sleep(100);
}
printf("\n");
LeaveCriticalSection(&g_csA);
}
return 0;
}
///
HANDLE g_hEvent;
UINT WINAPI PrintThread3(LPVOID lp)
{
while (1)
{
DWORD dwResult = WaitForSingleObject(g_hEvent, INFINITE);
if (dwResult == WAIT_OBJECT_0)
{
for (int i=0;i<3;i++)
{
printf("thread3\n");
Sleep(500);
}
printf("\n");
}
SetEvent(g_hEvent);
}
return 0;
}
UINT WINAPI PrintThread4(LPVOID lp)
{
while (1)
{
DWORD dwResult = WaitForSingleObject(g_hEvent, INFINITE);
if (dwResult == WAIT_OBJECT_0)
{
for (int i=0;i<3;i++)
{
printf("thread4\n");
Sleep(300);
}
printf("\n");
}
SetEvent(g_hEvent);
}
return 0;
}
///
HANDLE g_hMutex;
UINT WINAPI PrintThread5(LPVOID lp)
{
while (1)
{
DWORD dwResult = WaitForSingleObject(g_hMutex, 500);//当前线程拥有该互斥量
if (dwResult == WAIT_OBJECT_0)
{
for (int i=0;i<3;i++)
{
printf("thread5\n");
Sleep(200);
}
printf("\n");
}
if (!ReleaseMutex(g_hMutex))//当前线程释放该互斥量
{
DWORD dwError = GetLastError();
if (dwError == ERROR_NOT_OWNER)
{
printf("thread5 error:ERROR_NOT_OWNER\n");
}
else
{
printf("thread5 error:%d\n", dwError);
}
}
}
return 0;
}
UINT WINAPI PrintThread6(LPVOID lp)
{
while (1)
{
DWORD dwResult = WaitForSingleObject(g_hMutex, 1000);
if (dwResult == WAIT_OBJECT_0)
{
for (int i=0;i<3;i++)
{
printf("thread6\n");
Sleep(400);
}
printf("\n");
}
if (!ReleaseMutex(g_hMutex)) //如果互斥量被线程5占有,那么当前线程将无法释放,只有占有者可以释放
{
DWORD dwError = GetLastError();
if (dwError == ERROR_NOT_OWNER)
{
printf("thread6 error:ERROR_NOT_OWNER\n");
}
else
{
printf("thread6 error:%d\n", dwError);
}
}
}
return 0;
}
//
HANDLE g_hDemaphore;
UINT WINAPI PrintThread7(LPVOID lp)
{
while (1)
{
DWORD dwResult = WaitForSingleObject(g_hDemaphore, INFINITE);//占用一个资源计数
if (dwResult == WAIT_OBJECT_0)
{
printf("Anglela");
Sleep(1000);
}
LONG count;
ReleaseSemaphore(g_hDemaphore,1,&count);//释放一个资源计数
}
return 0;
}
UINT WINAPI PrintThread8(LPVOID lp)
{
while (1)
{
DWORD dwResult = WaitForSingleObject(g_hDemaphore, INFINITE);//减少一个资源计数(如果还有资源计数)
if (dwResult == WAIT_OBJECT_0)
{
printf("Baby\n");
printf("\n");
Sleep(1000);
}
LONG count;
ReleaseSemaphore(g_hDemaphore,1,&count);//增加一个资源计数
Sleep(2000);// 减少后并不立即增加
}
return 0;
}
UINT WINAPI PrintThread9(LPVOID lp)
{
while (1)
{
DWORD dwResult = WaitForSingleObject(g_hDemaphore, INFINITE);
Sleep(1000);
if (dwResult == WAIT_OBJECT_0)
{
printf("Alice ");
Sleep(500);
}
LONG count;
BOOL bFlag = ReleaseSemaphore(g_hDemaphore,3,&count);
if (!bFlag)
{
printf("\n");
printf("thread9 release failed:%d\n", GetLastError());
}
}
return 0;
}
UINT WINAPI PrintThread10(LPVOID lp)
{
DWORD dwResult = 0;
while (1)
{
//减少2个资源计数
dwResult = WaitForSingleObject(g_hDemaphore, INFINITE);
dwResult = WaitForSingleObject(g_hDemaphore, INFINITE);
if (dwResult == WAIT_OBJECT_0)
{
printf("in Wonderland\n");
printf("\n");
Sleep(1000);
}
::EnterCriticalSection(&g_csB);
LONG count;// if rcount+pcount>maxcount,增加资源计数失败且当前资源计数不变
BOOL bFlag = ReleaseSemaphore(g_hDemaphore,2/*relasecount*/,&count/*previous count*/);//增加2个资源计数
if (!bFlag)
{
printf("\n");
printf("thread10 release failed:%d\n", GetLastError());
}
printf("thread10 previous count:%d\n", count);//执行release以前的资源计数
::LeaveCriticalSection(&g_csB);
}
return 0;
}
// 除了临界区,其他为内核对象,除了用于线程还可用于进程,可以通过创建时指定的名字打开夸进程使用
//
int _tmain(int argc, _TCHAR* argv[])
{
InitializeCriticalSection(&g_csA);
InitializeCriticalSection(&g_csB);
HANDLE m_hThread = NULL;
//同步与互斥:‘1个生产者-N个消费者’模型,同步有序-必须先生产然后消费,互斥无序,要么执行A,要么执行B,AB顺序未知
//由于线程1比线程2先执行,临界区保证打印结果thread1,thread2有序
//m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread1, NULL, 0, NULL);
//m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread2, NULL, 0, NULL);
//使用事件控制线程3,4有序执行
//创建一个命名的自动重置事件内核对象,第二个参数FALSE指定自动重置,第三个参数TRUE设置初始化为有信号
g_hEvent=CreateEvent(NULL,FALSE,TRUE,LPCWSTR("myevent"));
if (g_hEvent)
{
if (ERROR_ALREADY_EXISTS==GetLastError())
{
printf("error:event alread exist\n");
}
}
// 可以打开其他进程创建的事件对象
//$ g_hEvent = OpenEventA(EVENT_ALL_ACCESS, TRUE, LPCWSTR("myevent"));
//$ ResetEvent(g_hEvent);
//m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread3, NULL, 0, NULL);
//m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread4, NULL, 0, NULL);
//第二个参数TRUE,main线程拥有互斥量,体现互斥量‘线程拥有’的概念,区别事件‘先到先得’
g_hMutex = CreateMutexA(NULL, TRUE, "mymutex");
//$ g_hMutex = OpenMutexA(MUTEX_ALL_ACCESS, TRUE, "mymutex");
/*m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread5, NULL, 0, NULL);
m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread6, NULL, 0, NULL);
//$ 事件对象设置为自动重置与互斥量有类似功能
Sleep(3000);
printf("main thread release mutex\n");
printf("\n");
ReleaseMutex(g_hMutex);*/
// 信号量体现‘资源计数’的概念,通过修改初始计数与释放增加计算使打印有序
// SEMAPHORE_MODIFY_STATE,初始资源计数为2时,信号量为有信号状态,最大允许资源计数为10时,信号量为有信号状态
g_hDemaphore=CreateSemaphoreA(NULL,2,10,("Sem"));//初始资源计数为1,最大允许资源计数为2,通过release增加资源计数
//$ HANDLE semaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, _T("Global\\TestSemaphore"));
m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread7, NULL, 0, NULL);
m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread8, NULL, 0, NULL);
m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread9, NULL, 0, NULL);
m_hThread =(HANDLE)_beginthreadex(NULL, 0, PrintThread10, NULL, 0, NULL);
while (getchar()!='x')
{
}
DeleteCriticalSection(&g_csA);
DeleteCriticalSection(&g_csB);
CloseHandle(m_hThread);
CloseHandle(g_hEvent);
if (WaitForSingleObject(g_hMutex, 0) == WAIT_ABANDONED)
{
ReleaseMutex(g_hMutex);
}
CloseHandle(g_hMutex);
return 0;
}
1.线程1,2实现打印thread1,thread2有序,thread3~thread6实现类似打印功能;
2.线程7,8,9,10实现打印两个有序字符串,通过修改初始计数与增减计数实现打印有序;
3.MFC将4方法封装4个类功能相同,除了临界区,其他3个可以进程间使用。