网站大量收购闲置独家精品文档,联系QQ:2885784924

4:一个经典的多线程同步问题.doc

  1. 1、本文档共22页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
4:一个经典的多线程同步问题

一个经典的多线程同步问题 程序描述: 主线程启动10个子线程并将表示子线程序号的变量地址作为参数传递给子线程。子线程接收参数 - sleep(50) - 全局变量++ - sleep(0) - 输出参数和全局变量。 要求: 1.子线程输出的线程序号不能重复。 2.全局变量的输出必须递增。 下面画了个简单的示意图: 分析下这个问题的考察点,主要考察点有二个: 1.主线程创建子线程并传入一个指向变量地址的指针作参数,由于线程启动须要花费一定的时间,所以在子线程根据这个指针访问并保存数据前,主线程应等待子线程保存完毕后才能改动该参数并启动下一个线程。这涉及到主线程与子线程之间的同步。 2.子线程之间会互斥的改动和输出全局变量。要求全局变量的输出必须递增。这涉及到各子线程间的互斥。 ? 下面列出这个程序的基本框架,可以在此代码基础上进行修改和验证。 //经典线程同步互斥问题 #include stdio.h #include process.h #include windows.h long g_nNum; //全局资源 unsigned int __stdcall Fun(void *pPM); //线程函数 const int THREAD_NUM = 10; //子线程个数 int main() { g_nNum = 0; HANDLE handle[THREAD_NUM]; int i = 0; while (i THREAD_NUM) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, i, 0, NULL); i++;//等子线程接收到参数时主线程可能改变了这个i的值 } //保证子线程已全部运行结束 WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE); return 0; } unsigned int __stdcall Fun(void *pPM) { //由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来 int nThreadNum = *(int *)pPM; //子线程获取参数 Sleep(50);//some work should to do g_nNum++; //处理全局资源 Sleep(0);//some work should to do printf(线程编号为%d 全局资源值为%d\n, nThreadNum, g_nNum); return 0; } 运行结果: 可以看出,运行结果完全是混乱和不可预知的。运用Windows平台下各种手段包括关键段,事件,互斥量,信号量等等来解决这个问题。 关键段CRITICAL_SECTION首先介绍下如何使用关键段,然后再深层次的分析下关键段的实现机制与原理。 关键段CRITICAL_SECTION一共就四个函数,使用很是方便。下面是这四个函数的原型和使用说明。 ? 函数功能:初始化 函数原型: void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 函数说明:定义关键段变量后必须先初始化。 ? 函数功能:销毁 函数原型: void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 函数说明:用完之后记得销毁。 ? 函数功能:进入关键区域 函数原型: void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 函数说明:系统保证各线程互斥的进入关键区域。 ? 函数功能:离开关关键区域 函数原型: void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); ? 然后在经典多线程问题中设置二个关键区域。一个是主线程在递增子线程序号时,另一个是各子线程互斥的访问输出全局资源时。详见代码: #include stdio.h #include process.h #include windows.h long g_nNum; unsigned int __stdcall Fun(void *pPM); const int THREAD_NUM = 10; //关键段变量声明 CRITICAL_SECTION g_csThreadParameter, g_csThreadCode; int main() { printf(经典线程同步--关

文档评论(0)

ccx55855 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档