eLock singelLock(semaphore);
singleLock.Lock();
Sleep(10000);
::MessageBox((HWND)param,"Thread3 had access","Thread3",MB_OK);
return 0;
}
二、 编程步骤
1、 启动Visual C++6.0,生成一个32位的控制台程序,将该
程序命名为"sequence"
2、 输入要排续的数字,声明四个子线程;
3、 输入代码,编译运行程序。
三、 程序代码
//////////////////////////////////////////////////////////////////////////////////////
// sequence.cpp : Defines the entry point for the console application.
/*
主要用到的WINAPI线程控制函数,有关详细说明请查看MSDN;
线程建立函数:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全属性结构指针,可为NULL;
DWORD dwStackSize, // 线程栈大小,若为0表示使用默认值;
LPTHREAD_START_ROUTINE lpStartAddress, // 指向线程函数的指针;
LPVOID lpParameter, // 传递给线程函数的参数,可以保存一个指针值;
DWORD dwCreationFlags, // 线程建立是的初始标记,运行或挂起;
LPDWORD lpThreadId // 指向接收线程号的DWORD变量;
);
对临界资源控制的多线程控制的信号函数:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性结构指针,可为NULL;
BOOL bManualReset, // 手动清除信号标记,TRUE在WaitForSingleObject后必须手动//调用RetEvent清除信号。若为 FALSE则在WaitForSingleObject
//后,系统自动清除事件信号;
BOOL bInitialState, // 初始状态,TRUE有信号,FALSE无信号;
LPCTSTR lpName // 信号量的名称,字符数不可多于MAX_PATH;
//如果遇到同名的其他信号量函数就会失败,如果遇
//到同类信号同名也要注意变化;
);
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 安全属性结构指针,可为NULL
BOOL bInitialOwner, // 当前建立互斥量是否占有该互斥量TRUE表示占有,
//这样其他线程就不能获得此互斥量也就无法进入由
//该互斥量控制的临界区。FALSE表示不占有该互斥量
LPCTSTR lpName // 信号量的名称,字符数不可多于MAX_PATH如果
//遇到同名的其他信号量函数就会失败,
//如果遇到同类信号同名也要注意变化;
);
//初始化临界区信号,使用前必须先初始化
VOID InitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection // 临界区变量指针
);
//阻塞函数
//如果等待的信号量不可用,那么线程就会挂起,直到信号可用
//线程才会被唤醒,该函数会自动修改信号,如Event,线程被唤醒之后
//Event信号会变得无信号,Mutex、Semaphore等也会变。
DWORD WaitForSingleObject(
HANDLE hHandle, // 等待对象的句柄
DWORD dwMilliseconds // 等待毫秒数,INFINITE表示无限等待
);
//如果要等待多个信号可以使用WaitForMutipleObject函数
*/
#include "stdafx.h"
#include "stdlib.h"
#include "memory.h"
HANDLE evtTerminate; //事件信号,标记是否所有子线程都执行完
/*
下面使用了三种控制方法,你可以注释其中两种,使用其中一种。
注意修改时要连带修改临界区PrintResult里的相应控制语句
*/
HANDLE evtPrint; //事件信号,标记事件是否已发生
//CRITICAL_SECTION csPrint; //临界区
//HANDLE mtxPrint; //互斥信号,如有信号表明已经有线程进入临界区并拥有此信号
static long ThreadCompleted = 0;
/*用来标记四个子线程中已完成线程的个数,当一个子线程完成时就对ThreadCompleted进行加一操作, 要使用InterlockedIncrement(long* lpAddend)和InterlockedDecrement(long* lpAddend)进行加减操作*/
//下面的结构是用于传送排序的