Windows多线程总结(2)-- 多线程的使用

我们在实际应用中使用多线程的情况比较多,我们这里使用多线程模拟卖票的例子:

        我们定义一个全局的变量 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;
}



有可能运行一次出不来,可以多运行几次,下一篇文章去解决这个问题。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页