一种线程中挂时控的方法与流程

文档序号:12469448阅读:227来源:国知局
一种线程中挂时控的方法与流程
本发明涉及一种挂时控(设置定时器)的方法,特别是一种线程中挂时控的方法。
背景技术
:现阶段,多线程技术广泛应用在软件开发中,如果在线程中需要进行时控(或定时器)处理,目前基本上是使用sleep类似的阻塞定时方式,但在这种阻塞方式下,线程处于阻塞状态,不能处理其他消息或事务,弊端非常明显。如果直接像进程那样挂时控,对线程来说是无法确保一定能响应到时到信号(linux下一般使用SIGALRM信号)的,而且在线程中响应这些时到信号将会带来不可预估的后果,因此目前一直未有一种有效的在线程中以非阻塞方式挂时控的方法。技术实现要素:发明目的:本发明所要解决的技术问题(或目的)是在线程中以非阻塞方式挂时控并能响应处理时控的方法。技术方案:本发明提出了一种在线程中以非阻塞方式挂时控并能响应时控处理的方法。该方法主要包括以下步骤:步骤1,创建进程的时控队列timerList、挂时控函数setTimer_Thread以及时控响应函数timerFunction;进程由线程组成,如果是多线程,一般把线程分为主线程(有时代表进程)和子线程(或者叫次线程);步骤2,创建子线程及与主线程进行交互的消息链表,屏蔽掉子线程中时控信号,需要挂时控时,直接调用挂时控函数setTimer_Thread挂时控;步骤3,主线程响应时到信号,并执行时控响应函数timerFunction,将线程时控属性转换为时控消息加入到对应线程的消息链表中;步骤4,子线程取出时控消息,得到时控属性,根据时控属性进行相应的时控处理。步骤1中,所述时控队列timerList用于存储整个进程所有线程的时控;时控队列timerList中的每个时控项包含两个时控属性,分别为时控属性一和时控属性二,时控属性一用于指示线程ID,时控属性二用于指示时间属性ID;时控队列timerList中,各时控项按时控时到先后顺序依次排列;挂时控函数setTimer_Thread包含四个参数:时控属性一、时控属性二、时控标识和时间值,其中,时控标识用于指示是挂时控还是删除时控,时间值是指时控的相对于挂时控时的时间值;时控响应函数timerFunction为进程的时控响应函数,所有时到响应都首先执行此函数。步骤1中所述挂时控函数setTimer_Thread执行如下步骤:步骤1-1,根据时控属性一与时控属性二生成Hash关键字;步骤1-2,判定时控标识,如果为挂时控,则转到步骤1-3,如果是取消时控则转到步骤1-6;步骤1-3,根据Hash关键字找到时控项的存储位置,存储时控项;步骤1-4,根据时控的时到顺序,在时控队列timerList中找到对应的位置,插入该时控;步骤1-5,如果该时控处于时控队列timerList队首,则调用系统函数setitimer重挂进程的时控;步骤1-6,根据Hash关键字,找到该时控的存储位置及在时控队列中的位置;步骤1-7,从时控队列timerList中删除该时控;步骤1-8,如果该时控处于时控队列timerList队首,则调用系统函数setitimer根据时控队列timerList新队首的时控项重挂进程的时控。步骤2中,所述子线程与主线程进行交互的消息链表项包含三部分:消息长度、消息属性标识和消息内容,消息长度指消息的字节数;消息属性标识用于指示该消息是普通消息还是时控消息;消息内容即消息的详细内容,如果消息属性标识为1,则其前两个字节存储的是时控属性二。如果不为1,则存储的为消息的详细内容(字节串),消息长度指示了字节串中的字节数(前两个字节就是消息字节串的前两个字节)。步骤2中,每个子线程对应一个消息链表,主线程或子线程访问该消息链表时,利用线程锁进行加锁,访问结束解锁。线程中屏蔽掉时控信号,是为了只有主线程才能响应时控信号。线程中挂时控直接调用setTimer_Thread,其本质是线程把时控插入到进程的时控队列中,某一时刻在进程中实际上只有时控队列队首的时控在执行。步骤3中,所述主线程响应时到信号,并执行时控响应函数timerFunction,包括如下步骤:步骤3-1,从时控队列timerList队首取出一个时控项,并调整其下一个时控的前向指针;步骤3-2,判定时控项的时控属性一,如果为0,转向步骤3-3;如果为1,则转向步骤3-4;步骤3-3,主线程根据时控属性二进行相应的时控处理(时控处理是根据实际需要定义的,譬如应用每隔五分钟检查文件大小,达到1MB就转存,那么五分钟时控到了,时控处理就是检查文件大小,如果达到1MB就转存),然后转向步骤3-8;步骤3-4,根据时控属性一找到对应线程ID的子线程,把时控属性二封装成时控消息;步骤3-5,对该对应线程的消息链表加锁;步骤3-6,若该消息链表为空,直接插入时控消息;若不为空,则从头开始查找到第一个消息属性标识msgFlag为0的项,即第一个普通消息,在其前面插入时控消息;步骤3-7,对该消息链表解锁,并通知该子线程;步骤3-8,根据时控队列timerList队首的时控项,调用系统函数setitimer重新挂进程的时控。步骤4包括如下步骤:步骤4-1,屏蔽SIGALRM信号,确保线程不会响应进程的信号;步骤4-2,对消息链表加锁;步骤4-3,依次取出消息链表中的消息,存入线程的局部链表中;步骤4-4,对消息链表解锁;步骤4-5,从线程的局部链表中逐一取出消息处理;步骤4-6,判定消息属性标识msgFlag,如果为普通消息,转到步骤4-7,如果为时控消息,则转到步骤4-8;步骤4-7,对该普通消息进行处理,返回到步骤4-2;步骤4-8,从该时控消息中提取时控属性二,进行对应的时控处理;步骤4-9,返回到步骤4-2。本发明采用了独特的在线程中挂时控(本质为将线程时控插入到进程的时控队列中),由主线程(实际挂时控并)响应时到信号,再将线程的时控属性转换为线程时控消息传递给线程,线程从时控消息中获得时控属性并进行相应时控处理的方法,最终实现了在线程中以非阻塞方式挂时控并响应时控处理。有益效果:本发明采用了独特的在线程中挂时控(本质为将时控插入到进程的时控队列中),由主线程(实际挂时控并)响应时到信号,再将线程的时控属性转换为线程时控消息传递给线程,线程从时控消息中获得时控属性并进行相应时控处理的方法,最终实现了在线程中以非阻塞方式挂时控并响应时控处理。本发明实现原理简单可靠,通过工程实践证明,本发明是一种有效的在线程中以非阻塞方式挂时控的方法。下面结合附图对本发明作进一步详细描述。附图说明下面结合附图和具体实施方式对本发明做更进一步的具体说明,本发明的上述和/或其他方面的优点将会变得更加清楚。图1本发明的setTimer_Thread实现流程图。图2本发明的timerFunction实现流程图。图3本发明的子线程执行流程图。具体实施方式下面结合附图对本发明作具体说明。应该指出,所描述的实施例仅是为了说明的目的,而不是对本发明范围的限制。结合图1—图3,本发明包括以下处理步骤:步骤1,创建进程的时控队列timerList,挂时控函数setTimer_Thread,及时控响应函数timerFunction。其中时控队列timerList中的每个时控项包含两个时控属性,时控属性一用来指示线程ID,时控属性二指示时间属性ID;timerList中,各时控项按时控时到先后顺序依次排列。时控队列timerList中存储的详细数据信息如下表1:表1名称类型备注Attr1Unsignedshort时控属性一,为线程ID,其中0表示主线程Attr2Unsignedshort时控属性二,时间属性IDtimerFlagUnsignedchar时控标识,0-相对时控,1-绝对时控XtDouble相对时控值,距离当前时间的秒数JtDouble绝对时控值,距离1970年1月1日0点的秒数Prior指针前向指针Next指针后向指针挂时控函数setTimer_Thread包含四个参数:时控属性一,时控属性二,时控标识,时间值,其处理步骤如下(参见图1本发明的挂时控函数setTimer_Thread实现流程图):步骤1-1,根据时控属性一与时控属性二生成Hash关键字;步骤1-2,判定时控标识,如果为挂时控,则转到步骤1-3,如果是取消时控则转到步骤1-6;步骤1-3,根据Hash关键字找到时控项的存储位置,存储时控项;步骤1-4,根据时控的时到顺序,在时控队列timerList中找到对应的位置,插入该时控;步骤1-5,如果该时控处于时控队列timerList队首,则调用系统函数setitimer重挂进程的时控;步骤1-6,根据Hash关键字,找到该时控的存储位置及在时控队列中的位置;步骤1-7,从时控队列timerList中删除该时控;步骤1-8,如果该时控处于时控队列timerList队首,则调用系统函数setitimer根据时控队列timerList新队首的时控项重挂进程的时控。步骤2,创建子线程及其与主线程进行交互的消息链表,子线程中屏蔽掉时控信号,循环执行,需要挂时控时,直接调用setTimer_Thread挂时控。步骤2中,所述子线程与主线程进行交互的消息链表项包含三部分:消息长度、消息属性标识和消息内容,消息长度指消息的字节数;消息属性标识用于指示该消息是普通消息还是时控消息;消息内容即消息的详细内容,如果消息属性标识为1,则其前两个字节存储的是时控属性二。如果不为1,则存储的为消息的详细内容(字节串),消息长度指示了字节串中的字节数(前两个字节就是消息字节串的前两个字节)。消息链表项的详细数据信息如下表2:表2步骤3,时控到时,主线程响应时到信号执行时控响应函数timerFunction,其处理步骤如下(参见图2本发明的timerFunction实现流程图):步骤3-1,从时控队列timerList队首取出一个时控项,并调整其下一个时控的前向指针;步骤3-2,判定时控项的时控属性一,如果为0,转向步骤3-3;如果为1,则转向步骤3-4;步骤3-3,主线程根据时控属性二进行相应的时控处理,然后转向步骤3-8;步骤3-4,根据时控属性一找到对应线程ID的子线程,把时控属性二封装成时控消息;步骤3-5,对该对应线程的消息链表加锁;步骤3-6,若该消息链表为空,直接插入时控消息;若不为空,则从头开始查找到第一个消息属性标识msgFlag为0的项,即第一个普通消息,在其前面插入时控消息;步骤3-7,对该消息链表解锁,并通知该子线程;步骤3-8,根据时控队列timerList队首的时控项,调用系统函数setitimer重新挂进程的时控。步骤4,子线程取出时控消息进行时控处理,子线程运行处理步骤如下(参见图3本发明的子线程执行流程图):步骤4-1,屏蔽SIGALRM信号,确保线程不会响应进程的信号;步骤4-2,对消息链表加锁;步骤4-3,依次取出消息链表中的消息,存入线程的局部链表中;步骤4-4,对消息链表解锁;步骤4-5,从线程的局部链表中逐一取出消息处理;步骤4-6,判定消息属性标识msgFlag,如果为普通消息,转到步骤4-7,如果为时控消息,则转到步骤4-8;步骤4-7,对该普通消息进行处理,返回到步骤4-2;步骤4-8,从该时控消息中提取时控属性二,进行对应的时控处理;步骤4-9,返回到步骤4-2。步骤3、步骤4中,所有的时控时到时,首先由进程的timerFunction进行响应,该响应函数将根据时控属性一找到对应线程,将时控属性二转换为时控消息插入到该线程的消息链表中,而线程从消息链表中取出时控消息,根据时控消息中的时控属性Attr2,最终实现对应时控的处理。本发明提供了一种线程中挂时控的方法,具体实现该技术方案的方法和途径很多,以上所述仅是本发明的优选实施方式,应当指出,对于本
技术领域
的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。本实施例中未明确的各组成部分均可用现有技术加以实现。当前第1页1 2 3 
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1