我们在实际应用中使用多线程的情况比较多,我们这里使用多线程模拟卖票的例子:
我们定义一个全局的变量 int tickets = 200; 代表一共有200张票可以卖,通过两个窗口来卖,这两个窗口分别通过一个线程完成。示例如下:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <windows.h>
int tickets = 200;
DWORD WINAPI ThreadProc1(LPVOID lpThreadParameter)
{
while (TRUE)
{
if (tickets>0)//如果还有票的话 则打印输出 并自减
{
printf("thread1 ---- %d \n", tickets--);
}
else
{
break;
}
}
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpThreadParameter)
{
while (TRUE)
{
if (tickets > 0)
{
printf("thread2 ---- %d \n", tickets--);
}
else
{
break;
}
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
//创建两个线程
DWORD lpThreadId1 = 0;
HANDLE h1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, &lpThreadId1);
DWORD lpThreadId2 = 0;
HANDLE h2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, &lpThreadId2);
//关闭句柄
CloseHandle(h1);
CloseHandle(h2);
//打印新线程的ID
printf("%d \n", lpThreadId1);
printf("%d \n", lpThreadId2);
system("pause");
return 0;
}
我们会发现,能够完整的打印出来所有的票,由于线程获取时间片的问题,会导致有的线程打印的少,有的打印的多或者没有执行,这都是正常的现象。
不过要注意,上面的代码是存在缺陷的。为什么这么说呢? 是因为线程在执行的时候,CPU会分配时间片给不同的线程,如果有时间那么CPU就会执行该线程的代码,如果没有时间片,CPU则去执行其他得到执行权并有时间片的代码。 说这个的意思,是告诉大家,假设Ticktes是 1,当执行线程1 的时候,执行到进入了if但是还没有打印,此时时间片被释放了,CPU就会去执行线程2去了,并且执行完毕将1打印出来, 然后线程1获取到执行权,会接着打印,此时就会出现0号票, 0号票是不应该存在的,所以会有问题的。如何验证,在每个线程的输出语句前添加 Thread(1) 即可,代码如下:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <windows.h>
int tickets = 200;
DWORD WINAPI ThreadProc1(LPVOID lpThreadParameter)
{
while (TRUE)
{
if (tickets>0)
{
Sleep(1);
printf("thread1 ---- %d \n", tickets--);
}
else
{
break;
}
}
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpThreadParameter)
{
while (TRUE)
{
if (tickets > 0)
{
Sleep(1);
printf("thread2 ---- %d \n", tickets--);
}
else
{
break;
}
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD lpThreadId1 = 0;
HANDLE h1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, &lpThreadId1);
DWORD lpThreadId2 = 0;
HANDLE h2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, &lpThreadId2);
CloseHandle(h1);
CloseHandle(h2);
printf("%d \n", lpThreadId1);
printf("%d \n", lpThreadId2);
system("pause");
return 0;
}
有可能运行一次出不来,可以多运行几次,下一篇文章去解决这个问题。