当前位置: 首页 > news >正文

建设银行的网站进不去怎么办中建材建设有限公司网站

建设银行的网站进不去怎么办,中建材建设有限公司网站,网上培训机构,电商网站建设思路内核对象 要想掌握Windows平台下的线程#xff0c;应首先理解“内核对象”#xff08;Kernel Objects#xff09;的概念。如果仅介绍Windows平台下的线程使用技巧#xff0c;则可以省略相对陌生的内核对象相关内容。但这并不能使各位深入理解Windows平台下的线程。 内核对…内核对象 要想掌握Windows平台下的线程应首先理解“内核对象”Kernel Objects的概念。如果仅介绍Windows平台下的线程使用技巧则可以省略相对陌生的内核对象相关内容。但这并不能使各位深入理解Windows平台下的线程。 内核对象的定义 操作系统创建的资源有很多种如进程、线程、文件及即将介绍的信号量、互斥量等。其中大部分都是通过程序员的请求创建的而且请求方式各不相同。虽然存在一些差异但它们之间也有如下共同点“都是由Windows操作系统创建并管理的资源。” 不同资源类型在“管理”方式也有差异。例如文件管理中应注册并更新文件相关的数据I/O位置、文件的打并模式rcad or write等。如果是线程则应注册并维护线程ID、线程所属进程等信息。操作系统为了以记录相关信息的方式管理各种资源在其内部生成数据块。当然每种资源需要维护的信息不同所以每种资源拥有的数据块格式也有差异。这类数据块称为“内核对象”。 假设在Windows下创建了mydata.txt文件此时Windows操作系统将生成1个数据块以便管理该数据块就是内核对象。同理Windows在创建进程、线程、线程同步信号量时也会生成相应的内核对象用于管理操作系统资源。 内核对象归操作系统所有 线程、文件等资源的创建请求均在进程内部完成因此很容易产生“此时创建的内核对象所有者就是进程”的错觉。其实内核对象所有者是内核(操作系统。“所有者是内核”具有如下含义 “内核对象的创建、管理、销毁时机的决定等工作均由操作系统完成! 基于 Windows的线程创建 进程和线程的关系 既然在第18章学习过线程那么请回答如下问题“程序开始运行后调用main函数的主体是进程还是线程” 调用main函数的主体是线程实际上过去的正确答案可能是进程特别是在UNIX系列的操作系统中。因为早期的操作系统并不支持线程为了创建线程经常需要特殊的库函数支持。换言之操作系统无法意识到线程的存在而进程实际上成为运行的最小单位。即便在这种情况下需要线程的程序员们也会利用特殊的库函数以拆分进程运行时间的方式创建线程。但归根结底这仅仅是应用程序级别创建的线程与现在讨论的操作系统级别的线程存在巨大差异。 现代的Linux系列、Windows系列及各种规模不等的操作系统都在操作系统级别支持线程因此非显式创建线程的程序如基于select的服务器端可描述如下“单一线程模型的应用程序” 反之显式创建单独线程的程序可描述如下:“多线程模型的应用程序。”这就意味着main函数的运行同样基于线程完成此时进程可以比喻为装有线程的篮子。实际的运行主体是线程。 Windows 中线程的创建方法 调用该函数将创建线程操作系统为了管理这些资源也将同时创建内核对象。最后返回用于区分内核对象的整数型“句柄”(Handle)。第1章已介绍过句柄相当于Linux的文件描述符。 #include windows.h HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStacksize,LPTHREAD_START_ROUTINE IpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId ); //成功时返回线程句柄失败时返回NULL。IpThreadAttributes //线程安全相关信息使用默认设置时传递NULL。 dwStackSize //要分配给线程的栈大小,传递0时生成默认大小的栈。IpStartAddress //传递线程的main函数信息。lpParameter //调用main函数时传递的参数信息。dwCreationFlags //用于指定线程创建后的行为传递0时线程创建后立即进入可执行状态。 IpThreadld //用于保存线程ID的变量地址值。 上述定义看起来有些复杂其实只需要考虑IpStartAddress和lpParameter这2个参数剩下的只需传递0或NULL即可。 Windows线程的销毁时间点 Windows 线程在首次调用的线程main 函数返回时销毁销毁时间点和销毁方法与Linux不同。还有其他方法可以终止线程但最好的方法就是让线程main函数终止(返回)。 创建“使用线程安全标准C函数”的线程 之前介绍过创建线程时使用的CreateThread函数如果线程要调用C/C标准函数需要通过如 下方法创建线程。因为通过CreateThread函数调用创建出的线程在使用C/C标准函数时并不稳定。 #include process.h uintptr_t _beginthreadex(void * security,unsigned stack _size,unsigned (* start_address)(void *),void * arglist,unsigned initflag,unsigned * thrdaddr); //成功时返回线程句柄失败时返回0。上述函数与之前的CreateThread函数相比参数个数及各参数的含义和顺序的相同只是变 量名和参数类型有所不同。因此用上述函数替换CreateThread函数时只需适当更改数据类型。上述函数的返回值类型uintptr_t是64位unsigned整数型。但下述示例将通过声明CreateThread 函数的返回值类型HANDLE这同样是整数型保存返回的线程句柄。 #includestdio.h #includewindows.h #includeprocess.h unsigned WINAPI ThreadFunc(void*arg); //这个WINAPI只是函数调用惯例声明和链接时的操作有关int main(int argc,char *argv[]){HANDLE hThread;unsigned threadID;int param5;hThread(HANDLE)_beginthreadex(NULL,0,ThreadFunc,(void*)param,0,threadID);if(hTread0){puts(_beginthreadex() error);return -1;}sleep(3000);puts(end of main);return 0; }unsigned WINAPI ThreadFunc(void*arg){int i;int cnt*((int*)arg);for(i0;icnt;i){sleep(1000);puts(runnning thread);}return 0; } 与Linux相同Windows同样在main函数返回后终止进程也同时终止其中包含的所有线程。另外如果对上述代码进行运行的话最后输出的内容并非字符串end of main,而是running thread。但这是在main函数返回后完全销毁进程前输出的字符串。 句柄、内核对象和ID间的关系 线程也属于操作系统管理的资源因此会伴随着内核对象的创建并为了引用内核对象而返回句柄。可以利用句柄发送如下请求“我会一直等到该句柄指向的线程终止。”可以通过句柄区分内核对象通过内核对象可以区分线程。最终线程句柄成为区分线程的工具。那线程ID又是什么呢如上述示例所示通过_beginthreadex函数的最后一个参数可以获取线程ID。各位或许对句柄和ID的并存感到困惑其实它们有如下显著特点:“句柄的整数值在不同进程中可能出现重复但线程在跨进程范围内不会出现重复。线程ID用于区分操作系统创建的所有线程,但通常没有这种需求。 内核对象的2种状态 资源类型不同内核对象也含有不同信息。其中应用程序实现过程中需要特别关注的信息被赋予某种“状态”。例如线程内核对象中需要重点关注线程是否已终止所以终止状态又称“signaled状态”未终止状态称为“non-signaled状态”。 内核对象的状态及状态查看 我们通常比较关注进程的终止时间和线程的终止时间所以自然会问:“该进程何时终止”或“该线程何时终止”操作系统将这些重要信息保存到内核对象同时给出如下约定:“进程或线程终止时我会把相应的内核对象改为signaled状态这也意味着进程和线程的内核对象初始状态是non-signaled状态。那么内核对象的signaled、non-signaled状态究竟如何表示呢 非常简单通过1个boolean变量表示。内核对象带有1个boolean变量其初始值为FALSE此时的状态就是non-signaled状态。如果发生约定的情况把该变量改为TRUE此时的状态就是signaled状态。内核对象类型不同进入signaled状态的情况也有所区别(即对应事件也有区别)。 正常运行之前示例前需要考虑如下问题“该内核对象当前是否为signaled状态” 为回答类似问题系统定义了WaitForSingleObject和WaitForMultipleObjects函数。 WaitForSingleObject WaitForMultipleObjects 首先介绍WaitForSingleObject函数该函数针对单个内核对象验证signaled状态。 #includewindows.h DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds); //成功时返回事件信息失败时返回WAIT_FAILED。hHandle //查看状态的内核对象句柄。dwMilliseconds //以1/1000秒为单位指定超时传递INFINITE时函数不会返回直到内核对象变成 //signaled状态。返回值 //进入signaled状态返回WAIT_OBJECT_0超时返回WAIT_TIMEOUT。 该函数由于发生事件(变为signaled状态)返回时有时会把相应内核对象再次改为non-signaled状态。这种可以再次进入non-signaled状态的内核对象称为“auto-reset模式”的内核对象而不会自动跳转到non-signaled状态的内核对象称为“manual-reset模式”的内核对象。 即将介绍的函数与上述函数不同可以验证多个内核对象状态。 #includewindows.h DWORD WaitForMultipleObeject(DWORD nCount,const HANDLE * lpHandles,BOOL bWaitALL,DWORD dwMilliseconds); //成功时返回事件信息失败时返回WAIT_FAILED。nCount //需验证的内核对象数。IpHandles //存有内核对象句柄的数组地址值。bWaitAll //如果为TRUE则所有内核对象全部变为signaled时返回如果为FALSE则只要有1 //个对象的状态变为signaled就会返回。dwMilliseconds //以1/1000秒为单指定超时传递INFINITE时函数不会返回直到内核对象变为//signaled状态。 下面利用WaitForSingleObject函数尝试解决示例的问题。 #includestdio.h #includewindows.h #includeprocess.h unsigned WINAPI ThreadFunc(void *arg);int main(int argc,char *argv[]){HANDLE hTread;DWORD wr;unsigned threadID;int param5;hTread(HANDLE)_beginthreadex(NULL,0,ThreadFunc,(void*)param,0,threadID);if(hTread0){puts(_beginthreadex() error);return -1;}if((wrWaitForSingleObject(hThread,INFINITE))WAIT_FAILED){puts(thread wait error);return -1;}printf(wait result: %s \n,(wrWAIT_OBJECT_0)?signaled:time-out);puts(end of main);return 0; }unsigned WINAPI ThreadFunc(void *arg){int i;int cnt*((int*)arg);for(i0;icnt;i){Sleep(1000);puts(running thread);}return 0; } WaitForSingleObject WaitForMultipleObjects的演示 第18章在Linux平台下分析了临界区问题本章最后的内容将留给Windows平台下的临界区 问题。 #include stdio.h #include windows.h #include process.h #define NUM_THREAD 50 unsigned WINAPI threadInc(void * arg); unsigned WINAPI threadDes(void * arg); 1ong long num0;int main(int argc, char *argv[]){HANDLE tHandles[NUM_THREAD];int i;printf(sizeof long long: %d \n,sizeof(long,long));for(i0;iNUM_THREAD;i){if(i%2)tHandles[i](HANDLE)_beginthreadex(NULL,0, threadInc,NULL,0,NULL);else tHandles[i](HANDLE)_beginthreadex(NULL, 0, threadDes, NULL, 0, NULL);}WaitForMultipleObjects(NUM_THREAD,tHandles,TRUE,INFINITE);printf(result: %1ld \n,num);return 0; }unsigned WINAPI threadInc(void * arg){int i;for(i0; i50000000; i)num1;return 0; }unsigned WINAPI threadDes(void * arg){int i;for(i0; i50000000; i)num-1;return 0; } 即使多运行几次也无法得到正确结果而且每次结果都不同。可以利用第20章的同步技术得到预想的结果。
http://www.pierceye.com/news/209866/

相关文章:

  • 成都设计公司网站线上线下一体化营销
  • 网站你懂我意思正能量晚上下载注册公司需要多少钱手续费
  • 在线html网站开发广州网站排名优化公司
  • 如何在免费网站上做推扩自己怎么来建设网站
  • 福安市教育局建设网站做架构图简单的网站
  • 如何快速进行网站开发seo是什么东西
  • 网站建设需要具备哪些学编程多少钱学费
  • 建设工程许可证在那个网站办金融行业网站制作
  • 邢台专业做网站价格信息流广告是什么
  • 网站开发的母的目的和意义.建设购物平台网站
  • 立方米网站建设做淘宝客网站用什么程序好
  • 怎样做网站挣钱建筑资料软件
  • 涿州建设局网站苏州市高新区建设局网站
  • 个人soho要怎么做企业网站成都包装设计公司
  • 网站开发 chrome浏览器崩溃ruhe用dw做网站
  • 全屏网站 图片优化个人网站cms系统
  • 做我女朋友程序网站邵东做网站
  • 建设网站如何挂到网上wordpress首页添加幻灯
  • 汕头正规网站建设模板总部城乡建设网站 资料员
  • vs 2017c 怎么建设网站网站建设的数字化和互联网化
  • 南昌网站设计公司海南营销网站建设
  • 购物网站素材个人搭建网站教程
  • 青岛网站建设哪里好模板建站服务公司
  • 青色网站欣赏wordpress中文购物
  • 建站培训全国住房与城乡建设部网站
  • 唐山网站建设方案策划沧州网站建设联系电话
  • 网页制作和网站开发实验报告logo设计品牌
  • 摄影后期教程网站百度指数1000搜索量有多少
  • wp网站建设模板什么是网站的原型
  • 园林绿化网站建设上海著名室内设计公司