哲学家就餐问题——多线程代码学习

哲学家就餐问题,在网上看到一份代码,学习。。

#include <windows.h>  //HADNDLE
#include <process.h>
//#include <time.h>  //time(0)
//#include <stdlib.h>
#include "iostream"

using namespace std;

const unsigned int N=5;    //哲学家数目
const int THINKING=1;     //标记当前哲学家的状态,1表示思考(饱的)
const int HUNGRY=2;      //2表示得到饥饿,3表示正在吃饭
const int EATING=3;

HANDLE hPhilosopher[N];  
HANDLE semaphore[N];

HANDLE mutex;   //typedef void* HANDLE

DWORD WINAPI philosopherProc(LPVOID lpParameter) //返回DWORD(32位数据)的API函数
//typedef unsigned long DWORD 
//typedef WINAPI __stdcall 函数参数入栈方式从右到左,一般导出函数时用。
//typedef void* LPVOID
{
	int myid;
	char idStr[128];

	cout << int(<span style="font-family: Arial, Helvetica, sans-serif;">lpParameter</span>) << endl;
	return NULL;
}

int main()
{
	//srand(time(0));

	mutex = CreateMutex(NULL, false, NULL); //创建一个互斥变量
	for (int i = 0; i < N; i++)
	{
		semaphore[i] = CreateSemaphore(NULL, 1, 1, NULL); //创建一个新的信号量

		hPhilosopher[i] = CreateThread(NULL, 0,   //线程安全属性,堆栈大小
			philosopherProc, LPVOID(i),       //线程函数,线程参数(这里,把i转成LPVOID传递)
			CREATE_SUSPENDED, 0);   //线程创建属性(这里是挂起,所以下面有唤起),线程ID
	}

	for (int i = 0; i < N; i++)
	{
		ResumeThread(hPhilosopher[i]); //线程恢复函数
	}
	Sleep(2000);//给时间线程执行
	return 0;
}


1.  看到一些不熟悉的关键字比如HANDLE之类的,不要紧,它很可能就是你熟悉东西的封装,只是为了好表示而已。在vs2012中,鼠标放到该关键字上,会有定义显示。

2.  参数的传递:LPVOID(i), int(lpParameter)。先讲i转成void*。因为void*是地址,i是整数,整数可以表示地址,当然可以转成void*型。int(lpParameter),再把int型转回来。这其实就传递了一个int 型参数 i 嘛。至于这样做的好处,后面再慢慢体会。。

3. 在最初编译这个工程时出现了奇奇怪怪让人摸不着头脑的错误。原来是里面某些中文编码的问题。解决方法:



4.  在创建线程时,使用了CREATE_SUSPENDED参数,创建时挂起,所以后面使用了唤醒。

实验结果:



结果很随机。第一个 应该是冲突了cout<<int(lpParameter)后还没得及执行<<endl,就被抢占了。

5. 最后Sleep(2000)必须要有。如果没有,主线程很快终止,其创建的次线程也没有机会执行就被终止了。


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值