工具VS2015
分为两个线程分别代表两个购票窗口
#include "stdafx.h"
#include<stdio.h>
#include<windows.h>
#include<iostream>
using namespace std;
DWORD WINAPI buy1
(
LPVOID LPpARAMETER
);
DWORD WINAPI buy2
(
LPVOID lpParameter
);
int index = 0;
int tickets = 100;
HANDLE hMutex;
int main()
{
HANDLE hThread1;
HANDLE hThread2;
hMutex = CreateMutex(NULL, FALSE, NULL);
hThread1 = CreateThread(NULL, 0, buy1, NULL, 0, NULL);
hThread2 = CreateThread(NULL, 0, buy2, NULL, 0, NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
while (tickets)
Sleep(3000);
return 0;
}
DWORD WINAPI buy1(LPVOID lpParameter)
{
while (1)
{
WaitForSingleObject(hMutex, INFINITE);
Sleep(1);
if (tickets>0)
cout << "thread1 sell ticket:" << tickets-- << endl;
else
break;
ReleaseMutex(hMutex);
}
return 0;
}
DWORD WINAPI buy2(LPVOID lpParameter)
{
while (1)
{
WaitForSingleObject(hMutex, INFINITE);
Sleep(1);
if (tickets>0)
cout << "thread2 sell ticket:" << tickets-- << endl;
else
break;
ReleaseMutex(hMutex);
}
return 0;
}
function CreateThread(lpThreadAttributes: Pointer; 安全设置
dwStackSize: DWORD; 堆栈大小
lpStartAddress: TFNThreadStartRoutine; 入口函数
lpParameter: Pointer; 函数参数
dwCreationFlags: DWORD; 启动选项
var lpThreadId: DWORD 输出线程 ID
)
1:安全设置
CreateThread 的第一个参数 lpThreadAttributes 是指向 TSecurityAttributes 结构的指针, 一般都是置为NULL, 这表示没有访问限制;
2:堆栈大小
栈是私有的但堆是公用的,CreateThread 的第二个参数是分配给线程的堆栈大小. 这个值都是 0, 这表示使用系统默认的大小, 默认和主线程栈的大小一样, 如果不够用会自动增长;
3:入口函数指针
到了入口函数了, 学到这个地方, 这个函数的标准返回值应该是 DWORD, 等线程退出后, 我们用 GetExitCodeThread 函数获取的退出码就是这个返回值! 如果线程没有退出, GetExitCodeThread 获取的退出码将是一个常量 STILL_ACTIVE (259); 这样我们就可以通过退出码来判断线程是否已退出,线程函数不能是某个类的方法。CreateThread 第三个参数是函数指针, 新线程建立后将立即执行该函数, 函数执行完毕, 系统将销毁此线程从而结束多线程的故事.
4:函数参数
线程入口函数的参数是个无类型指针(Pointer), 用它可以指定任何数据; 本例是把鼠标点击窗体的坐标传递给线程的入口函数, 每次点击窗体都会创建一个线程.
5:启动选项
dwCreationFlags(启动选项) 有两个可选值: 0: 线程建立后立即执行入口函数; CREATE_SUSPENDED: 线程建立后会挂起等待.
ResumeThread 恢复线程的运行; SuspendThread 挂起线程. 这两个函数的参数都是线程句柄, 返回值是执行前的挂起计数. SuspendThread 会给这个数 +1; ResumeThread 会给这个数 -1; 但这个数最小是 0. 当这个数 = 0 时, 线程会运行; > 0 时会挂起.
6:输出线程ID
CreateThread 的最后一个参数是 "线程的 ID",线程的 ID 是唯一的; 而句柄可能不只一个, 所以要获取ID,而且ID 比句柄更轻便.