永发信息网

VC创建的线程里面的程序何时运行,线程里的程序是否一直会一直运行,例如线程里的程序:getdi()。

答案:2  悬赏:40  手机版
解决时间 2021-02-28 17:48
getdi()能否反复运行
最佳答案
当创建线程时或者唤醒已存在的线程时,线程函数体会执行,如果线程体内没有循环,也是一遍过的,跟主线程一样,在线程体内是顺序执行的。
全部回答
有许多应用程序创建的线程花费了大量时间在睡眠状态来等待事件的发生。还有一些线程进入睡眠状态后定期被唤醒以轮询工作方式来改变或者更新状态信息。线程池可以让你更有效地使用线程,它为你的应用程序提供一个由系统管理的工作者线程池。至少会有一个线程来监听放到线程池的所有等待操作,当等待操作完成后,线程池中将会有一个工作者线程来执行相应的回调函数。 你也可以把没有等待操作的工作项目放到线程池中,用queueuserworkitem函数来完成这个工作,把要执行的工作项目函数通过一个参数传递给线程池。工作项目被放到线程池中后,就不能再取消了。 timer-queuetimers和registeredwaitoperations也使用线程池来实现。他们的回调函数也放在线程池中。你也可以用bindiocompletioncallback函数来投递一个异步io操作,在io完成端口上,回调函数也是由线程池线程来执行。 当第一次调用queueuserworkitem函数或者bindiocompletioncallback函数的时候,线程池被自动创建,或者timer-queuetimers或者registeredwaitoperations放入回调函数的时候,线程池也可以被创建。线程池可以创建的线程数量不限,仅受限于可用的内存,每一个线程使用默认的初始堆栈大小,运行在默认的优先级上。 线程池中有两种类型的线程:io线程和非io线程。io线程等待在可告警状态,工作项目作为apc放到io线程中。如果你的工作项目需要线程执行在可警告状态,你应该将它放到io线程。 非io工作者线程等待在io完成端口上,使用非io线程比io线程效率更高,也就是说,只要有可能的话,尽量使用非io线程。io线程和非io线程在异步io操作没有完成之前都不会退出。然而,不要在非io线程中发出需要很长时间才能完成的异步io请求。 正确使用线程池的方法是,工作项目函数以及它将会调用到的所有函数都必须是线程池安全的。安全的函数不应该假设线程是一次性线程的或者是永久线程。一般来说,应该避免使用线程本地存储和发出需要永久线程的异步io调用,比如说regnotifychangekeyvalue函数。如果需要在永久线程中执行这样的函数的话,可以给queueuserworkitem传递一个选项wt_executeinpersistentthread。 注意,线程池不能兼容com的单线程套间(sta)模型。 为了更深入地讲解操作系统实现的线程池的优越性,我们首先尝试着自己实现一个简单的线程池模型。 代码如下: typedefstruct_thread_pool { handlequitevent; handleworkitemsemaphore; longworkitemcount; list_entryworkitemheader; critical_sectionworkitemlock; longthreadnum; handle*threadsarray; }thread_pool,*pthread_pool; typedefvoid(*work_item_proc)(pvoidparam); typedefstruct_work_item { list_entrylist; work_item_procuserproc; pvoiduserparam; }work_item,*pwork_item; dwordwinapiworkerthread(pvoidpparam) { pthread_poolpthreadpool=(pthread_pool)pparam; handleevents[2]; events[0]=pthreadpool->quitevent; events[1]=pthreadpool->workitemsemaphore; for(;;) { dworddwret=waitformultipleobjects(2,events,false,infinite); if(dwret==wait_object_0) break; // //executeuser'sproc. // elseif(dwret==wait_object_0+1) { pwork_itempworkitem; plist_entryplist; entercriticalsection(&pthreadpool->workitemlock); _assert(!islistempty(&pthreadpool->workitemheader)); plist=removeheadlist(&pthreadpool->workitemheader); leavecriticalsection(&pthreadpool->workitemlock); pworkitem=containing_record(plist,work_item,list); pworkitem->userproc(pworkitem->userparam); interlockeddecrement(&pthreadpool->workitemcount); free(pworkitem); } else { _assert(0); break; } } return0; } boolinitializethreadpool(pthread_poolpthreadpool,longthreadnum) { pthreadpool->quitevent=createevent(null,true,false,null); pthreadpool->workitemsemaphore=createsemaphore(null,0,0x7fffffff,null); pthreadpool->workitemcount=0; initializelisthead(&pthreadpool->workitemheader); initializecriticalsection(&pthreadpool->workitemlock); pthreadpool->threadnum=threadnum; pthreadpool->threadsarray=(handle*)malloc(sizeof(handle)*threadnum); for(inti=0;i<threadnum;i++) { pthreadpool->threadsarray[i]=createthread(null,0,workerthread,pthreadpool,0,null); } returntrue; } voiddestroythreadpool(pthread_poolpthreadpool) { setevent(pthreadpool->quitevent); for(inti=0;i<pthreadpool->threadnum;i++) { waitforsingleobject(pthreadpool->threadsarray[i],infinite); closehandle(pthreadpool->threadsarray[i]); } free(pthreadpool->threadsarray); closehandle(pthreadpool->quitevent); closehandle(pthreadpool->workitemsemaphore); deletecriticalsection(&pthreadpool->workitemlock); while(!islistempty(&pthreadpool->workitemheader)) { pwork_itempworkitem; plist_entryplist; plist=removeheadlist(&pthreadpool->workitemheader); pworkitem=containing_record(plist,work_item,list); free(pworkitem); } } boolpostworkitem(pthread_poolpthreadpool,work_item_procuserproc,pvoiduserparam) { pwork_itempworkitem=(pwork_item)malloc(sizeof(work_item)); if(pworkitem==null) returnfalse; pworkitem->userproc=userproc; pworkitem->userparam=userparam; entercriticalsection(&pthreadpool->workitemlock); inserttaillist(&pthreadpool->workitemheader,&pworkitem->list); leavecriticalsection(&pthreadpool->workitemlock); interlockedincrement(&pthreadpool->workitemcount); releasesemaphore(pthreadpool->workitemsemaphore,1,null); returntrue; } voiduserproc1(pvoiddwparam) { workitem(dwparam); } voidtestsimplethreadpool(boolbwaitmode,longthreadnum) { thread_poolthreadpool; initializethreadpool(&threadpool,threadnum); completeevent=createevent(null,false,false,null); begintime=gettickcount(); itemcount=20; for(inti=0;i<20;i++) { postworkitem(&threadpool,userproc1,(pvoid)bwaitmode); } waitforsingleobject(completeevent,infinite); closehandle(completeevent); destroythreadpool(&threadpool); } 我们把工作项目放到一个队列中,用一个信号量通知线程池,线程池中任意一个线程取出工作项目来执行,执行完毕之后,线程返回线程池,继续等待新的工作项目。 线程池中线程的数量是固定的,预先创建好的,永久的线程,直到销毁线程池的时候,这些线程才会被销毁。 线程池中线程获得工作项目的机会是均等的,随机的,并没有特别的方式保证哪一个线程具有特殊的优先获得工作项目的机会。 而且,同一时刻可以并发运行的线程数目没有任何限定。事实上,在我们的执行计算任务的演示代码中,所有的线程都并发执行。 下面,我们再来看一下,完成同样的任务,系统提供的线程池是如何运作的。 dwordbegintime; longitemcount; handlecompleteevent; intcompute() { srand(begintime); for(inti=0;i<20*1000*1000;i++) rand(); returnrand(); } dwordwinapiworkitem(lpvoidlpparameter) { boolbwaitmode=(bool)lpparameter; if(bwaitmode) sleep(1000); else compute(); if(interlockeddecrement(&itemcount)==0) { printf("timetotal%dsecond.\n",gettickcount()-begintime); setevent(completeevent); } return0; } voidtestworkitem(boolbwaitmode,dwordflag) { completeevent=createevent(null,false,false,null); begintime=gettickcount(); itemcount=20; for(inti=0;i<20;i++) { queueuserworkitem(workitem,(pvoid)bwaitmode,flag); } waitforsingleobject(completeevent,infinite); closehandle(completeevent); } 很简单,是吧?我们仅需要关注于我们的回调函数即可。但是与我们的简单模拟来比,系统提供的线程池有着更多的优点。 首先,线程池中线程的数目是动态调整的,其次,线程池利用io完成端口的特性,它可以限制并发运行的线程数目,默认情况下,将会限制为cpu的数目,这可以减少线程切换。它挑选最近执行过的线程再次投入执行,从而避免了不必要的线程切换。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
高中化学元素原子的电子层排布表要背吗?
皮肤下长了个硬硬的,摸上去会痛,第二天就变大
散户炒股应该注意哪些问题?
电脑好像中病毒了,小键盘上的灯都不亮,开机
电子科技大学清水河校区-博士生公寓3栋地址在
求有哪些手机拍照软件带有长时间曝光功能(B
只养一胎(打一统计用语)
李泽明被禁赛了么
【水是生命之源】水是生命之源―—作文500字
恒安福购物广场在哪里啊,我有事要去这个地方
美国敢对中国动武吗
zotac gt610-1gd3冰铠士vd怎么样
我想起个音译的英文名
微信的各项转发软件都是从哪里弄到代理的
如何强力删除文件或文件夹
推荐资讯
下列地区的环境问题,有可能影响到全球环境的
原点1对1在哪里啊,我有事要去这个地方
三个又,四个又.怎么读
entity framework code first 如何在代码中设
关于亚洲季风的叙述,正确的是A. 东亚季风的
尚景捷讯地址在什么地方,想过去办事
郑州润皮景观园林工程有限公司地址有知道的么
方太厨电质量怎么样谁可以说下
惠阳新圩电信的20兆以上的光纤网络一个月多少
类似于dota的单机游戏,除了魔兽争霸,谢谢
求小说,男女主是银野彻和萧染染,校园小说,
天正建筑中自动保存的命令是什么 我在画图时
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?