线程调度方法和装置与流程

文档序号:11620430阅读:287来源:国知局
线程调度方法和装置与流程

本发明涉及操作系统技术领域,特别是涉及一种线程调度方法和装置。



背景技术:

棋牌游戏开发中,普遍使用多进程单线程模型作为服务器的基本架构,使用多进程可以由调度程序对来自客户端的请求进行分流,避免单一进程处理量过大,同时,更好地利用了cpu(centralprocessingunit,中央处理器)的工作效率,使用单线程,可以避免进程运行过程中线程切换带来的系统开销,同时单线程情况下不存在死锁现象,简化了编码流程,加快了游戏开发速度。但同时,单线程模型的程序也有缺点,比如,因为某种原因需要同步数据而造成线程阻塞,则该线程只能处于休眠状态,等待数据返回才能重新唤醒该线程继续处理逻辑,在这个休眠的过程中,它不会对其它请求进行处理,这样会影响其它请求的响应速度。而在一个游戏中,往往伴随着复杂的处理和各种数据的同步,若使用单线程模型,如果同步数据所需的时间越长,则线程处于休眠状态的时间也越长,对其它请求的处理也就会相应变慢。



技术实现要素:

基于此,有必要针对问题,提供一种线程调度方法,能够在减少进程运行中线程切换带来系统开销的同时提高服务器处理客户端请求的速度。

此外,还有必要针对问题,提供一种线程调度装置,能够在减少进程运行中线程切换带来系统开销的同时提高服务器处理客户端请求的速度。

一种线程调度方法,包括以下步骤:

启动第一线程和第二线程,并使所述第二线程进入休眠状态;

通过所述第一线程监听客户端请求;

通过所述第一线程判断所述客户端请求是否为同步数据请求;

若否,则通过所述第一线程处理所述客户端请求,并将处理结果返回客户 端;

若是,则通过所述第一线程唤醒所述第二线程,以使所述第二线程处理所述客户端请求,并将处理结果返回客户端。

在其中一个实施例中,所述通过所述第一线程唤醒所述第二线程,以使所述第二线程处理所述客户端请求,并将处理结果返回客户端,具体包括:

通过所述第一线程获取与所述客户端请求相关的数据;

将与所述客户端请求相关的数据存储在预设的数据容器中;

通过所述第一线程唤醒所述第二线程;

通过所述第二线程读取所述数据容器的数据,根据读取的数据进行相应处理,并将处理结果返回客户端。

在其中一个实施例中,所述将与所述客户端请求相关的数据存储在预设的数据容器中,具体为:

将所述与所述客户端请求相关的数据按照预设的数据格式通过链表的形式存储在预设的数据容器中;

所述与所述客户端请求相关的数据包括客户端身份标识、第一线程运算结果及所需访问的同步数据。

在其中一个实施例中,所述通过所述第二线程读取所述数据容器的数据,根据读取的数据进行相应处理,并将处理结果返回客户端,具体包括:

通过所述第二线程读取所述数据容器中的任务,所述任务通过所述预设的数据格式表示;

使所述第二线程根据所述任务的所需访问的同步数据从第三方同步接口中获取所述同步数据;

使所述第二线程根据所述任务的第一线程运算结果及所述同步数据进行运算;

使所述第二线程根据所述任务的客户端身份标识将运算结果返回给客户端。

在其中一个实施例中,在使所述第二线程根据所述任务的客户端身份标识将运算结果返回给客户端的步骤之后,还包括:

将从数据容器中读取并处理的任务从所述数据容器中移除;

通过所述第二线程判断所述数据容器中是否还有未处理的任务,若是,则使所述第二线程继续读取所述数据容器中的任务并处理,若否,则使所述第二线程进入休眠状态。

一种线程调度装置,包括:

启动模块,用于启动第一线程和第二线程,并使所述第二线程进入休眠状态;

监听模块,用于通过所述第一线程监听客户端请求;

判断模块,用于通过所述第一线程判断所述客户端请求是否为同步数据请求;

第一处理模块,用于当所述第一线程判断出所述客户端请求不是同步数据请求时,则通过所述第一线程处理所述客户端请求,并将处理结果返回客户端;

第二处理模块,用于当所述第一线程判断出所述客户端请求是同步数据请求时,则通过所述第一线程唤醒所述第二线程,以使所述第二线程处理所述客户端请求,并将处理结果返回客户端。

在其中一个实施例中,所述第二处理模块包括:

获取单元,用于通过所述第一线程获取与所述客户端请求相关的数据;

存储单元,用于将与所述客户端请求相关的数据存储在预设的数据容器中;

唤醒单元,用于通过所述第一线程唤醒所述第二线程;

处理单元,用于通过所述第二线程读取所述数据容器的数据,根据读取的数据进行相应处理,并将处理结果返回客户端。

在其中一个实施例中,所述存储单元还用于将所述与所述客户端请求相关的数据按照预设的数据格式通过链表的形式存储在预设的数据容器中;

所述与所述客户端请求相关的数据包括客户端身份标识、第一线程运算结果及所需访问的同步数据。

在其中一个实施例中,所述处理单元包括:

读取子单元,用于通过所述第二线程读取所述数据容器中的任务,所述任 务通过所述预设的数据格式表示;

获取子单元,用于使所述第二线程根据所述任务的所需访问的同步数据从第三方同步接口中获取所述同步数据;

运算子单元,用于使所述第二线程根据所述任务的第一线程运算结果及所述同步数据进行运算;

返回子单元,用于使所述第二线程根据所述任务的客户端身份标识将运算结果返回给客户端。

在其中一个实施例中,所述处理单元还包括:

移除子单元,用于将从数据容器中读取并处理的任务从所述数据容器中移除;

判断子单元,用于通过所述第二线程判断所述数据容器中是否还有未处理的任务,若是,则使所述第二线程继续读取所述数据容器中的任务并处理,若否,则使所述第二线程进入休眠状态。

上述线程调度方法和装置,当第一线程监听到同步数据请求,即当第一线程监听到会造成线程阻塞的客户端请求时,唤醒第二线程,由第二线程处理该客户端请求,可以有效区分阻塞型业务和非阻塞型业务,进而采用不同流程进行处理,能够在减少进程运行中线程切换带来系统开销的同时提高服务器处理客户端请求的速度,有效提高客户端的访问速度。

附图说明

图1为一个实施例中线程调度方法的步骤示意图;

图2为一个实施例中通过第一线程唤醒第二线程,使第二线程处理客户端请求的步骤示意图;

图3为一个实施例中通过第二线程处理数据容器中的任务的步骤示意图;

图4为一个实施例中数据容器的存储结构示意图;

图5为一个实施例中线程调度装置的结构示意图;

图6为一个实施例中第二处理模块的内部结构示意图;

图7为一个实施例中处理单元的内部结构示意图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅用以解释本发明,并不用于限定本发明。

如图1所示,一种线程调度方法,包括以下步骤:

步骤s110,启动第一线程和第二线程,并使第二线程进入休眠状态。

具体的,进程是程序的基本执行实体,是指令、数据及其组织形式的描述,进程是程序的实体。线程是程序中一个单一的顺序控制流程,是进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派cpu的基本单位及运行中的程序的调度单位。

服务器启动后,可调用pthread_create函数创建第二线程,并将第二线程与第一线程关联,第二线程可专用于处理与第一线程相关的阻塞业务。阻塞是指调用结果返回之前,当前线程会被挂起,即当前线程进入非可执行状态,在这个状态下,cpu不会给该线程分配时间片,该线程暂停运行,函数只有在得到结果之后才会返回。阻塞业务即指会使当前线程进入阻塞状态的客户端请求。第二线程被创建后,可调用pthread_cond_wait函数先令第二线程进入休眠状态,直至第一线程监听到有阻塞业务需要进行处理时,再唤醒第二线程,由第二线程进行处理。将第二线程暂时休眠,等有阻塞业务需要处理时再唤醒,在第二线程的休眠期间节省了cpu的占用,节约了系统资源。

步骤s120,通过第一线程监听客户端请求。

具体的,第一线程监听并处理由客户端发送的客户端请求。

步骤s130,通过第一线程判断该客户端请求是否为同步数据请求,若是,则执行步骤s140,若否,则执行步骤s150。

具体的,同步指的是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,也就是必须一件一件事做,等前一件做完了才能做下一件事。同步数据请求即为该客户端请求需要获取同步数据才可进行处理,例如需要到第三方的mysql(关系型数据库管理系统)服务器上请求相关数据,因mysql服务 器只提供同步接口,若要访问mysql的数据,则必须等待直至数据从mysql返回,会造成线程阻塞,即该客户端请求为阻塞业务。

步骤s140,通过第一线程唤醒第二线程,以使第二线程处理客户端请求,并将处理结果返回客户端。

具体的,当第一线程监听到客户端请求为同步数据请求时,第一线程唤醒第二线程,由第二程处理该客户端请求。第二线程根据该客户端请求获取同步数据进行处理,并将最终处理结果返回客户端。

步骤s150,通过第一线程处理该客户端请求,并将处理结果返回客户端。

具体的,若第一线程监听到的客户端请求不是同步数据请求,则表示处理过程中不需要获取同步数据,即为非阻塞业务,则由第一线程直接进行处理,并将处理结果返回给客户端。

上述线程调度方法,当第一线程监听到同步数据请求,即当第一线程监听到会造成线程阻塞的客户端请求时,唤醒第二线程,由第二线程处理该客户端请求,可以有效区分阻塞型业务和非阻塞型业务,进而采用不同流程进行处理,能够在减少进程运行中线程切换带来系统开销的同时提高服务器处理客户端请求的速度,有效提高客户端的访问速度,服务器对客户端响应快。

如图2所示,在一个实施例中,步骤s140通过第一线程唤醒第二线程,以使第二线程处理客户端请求,并将处理结果返回客户端,具体包括以下步骤:

步骤s202,通过第一线程获取与客户端请求相关的数据。

具体的,当客户端请求为同步数据请求时,第一线程需先获取与该客户端请求相关的数据。与客户端请求相关的数据包括客户端身份标识、第一线程运算结果及所需访问的同步数据等,其中,第一线程运算结果指的是第一线程在之前计算出的与该客户端请求相关的运算结果。

步骤s204,将与客户端请求相关的数据存储在预设的数据容器中。

具体的,服务器可预设一个数据容器用于存放与阻塞业务相关的数据,当第一线程监听到客户端请求为同步数据请求时,可将与该客户端请求相关的数据存储在预设的数据容器中,当第二线程被唤醒后,即可从数据容器中读取数据并进行处理。在一个实施例中,步骤s204具体为将与客户端请求相关的数据 按照预设的数据格式通过链表的形式存储在预设的数据容器中,例如,预设的数据格式可包括三个内容,内容1为客户端身份标识,内容2为第一线程运算结果,内容3为所需访问的同步数据,一个数据结构表示一个任务,并通过链表的形式进行存储。可以理解地,与客户端请求的数据也可以其它的数据结构进行存储。当第二线程读取数据容器中的数据时,可按链表上的顺序依次处理数据容器中的任务。

步骤s206,通过第一线程唤醒第二线程。

具体的,第一线程可通过调用pthread_cond_signal函数唤醒第二线程。

步骤s208,通过第二线程读取数据容器的数据,根据读取的数据进行相应处理,并将处理结果返回客户端。

具体的,第二线程被唤醒后,读取数据容器中由第一线程存储的数据,并进行解析,根据处理流程进行处理,最后将处理结果返回客户端。

如图3所示,在一个实施例中,步骤s208通过第二线程读取数据容器的数据,根据读取的数据进行相应处理,并将处理结果返回客户端,具体包括:

步骤s302,通过第二线程读取数据容器中的任务。

具体的,如图4所示,数据容器中的数据通过链表的形式存储,链表中的任务通过预设的数据结构表示,数据结构包括三个内容,内容1为客户端身份标识,内容2为第一线程运算结果,内容3为所需访问的同步数据,每个任务代表一个需要获取同步数据的客户端请求。

步骤s304,使第二线程根据任务的所需访问同步数据从第三方同步接口中获取同步数据。

具体的,第二线程读取数据容器中的任务并解析,可得到任务中数据结构中的内容。第二线程可先根据解析得到的所需访问的同步数据通过第三方同步接口进行访问,并等待第三方将数据返回。例如,所需访问的同步数据为uid(useridentification,用户身份标识)100的玩家现在金币的具体数值,则第二线程向mysql服务器发送请求,并等待数据返回,获取所需的同步数据。

步骤s306,使第二线程根据任务的第一线程运算结果及同步数据进行运算。

具体的,第二线程获取到所需的同步数据后,可根据解析得到的第一线程 运算结果与同步数据一起进行运算,例如,第一线程运算结果为uid100的玩家通过任务可获得的金币的具体数据为100金币,同步数据为uid100的玩家当前金币的具体数据为1000金币,通过运算可得到uid100的玩家在任务完成后背包中的金币的具体数值为1100金币。

步骤s308,使第二线程根据任务的客户端身份标识将运算结果返回给客户端。

具体的,第二线程可根据解析得到的客户端身份标识将运算结果返回给对应的客户端,返回成功后即表示该任务处理完成。

步骤s310,将从数据容器中读取并处理的任务从数据容器中移除。

具体的,当任务完成后,可将处理成功的任务从数据容器中移除,避免任务被重覆执行处理。

步骤s312,通过第二线程判断数据容器中是否还有未处理的任务,若是,则执行步骤s304,若否,则执行步骤s314。

具体的,第二线程可查看数据容器中是否还有未处理的任务,若是,则第二线程继续读取并处理数据容器中的任务,直至数据容器中的任务量变为0,例如,如图4中所示,在任务1后还有任务2,则第二线程处理完任务1后还需处理任务2,直至任务被全部处理完。若数据容器中没有未处理的任务,则可重新调用pthread_cond_wait函数使第二线程进入休眠状态,等待下一次有阻塞业务需要处理时再被唤醒。

步骤s314,使第二线程进入休眠状态。

上述线程调度方法,当第一线程监听到客户端请求为同步数据请求时,可将与该客户端请求相关的数据存储在数据容器中,并唤醒第二线程处理数据容器中的数据,第一线程可继续处理非阻塞业务,由第二线程处理阻塞业务,第一线程与第二线程互不影响,可以有效区分阻塞型业务和非阻塞型业务,进而采用不同流程进行处理,能够在减少进程运行中线程切换带来系统开销的同时提高服务器处理客户端请求的速度,有效提高客户端的访问速度。

如图5所示,一种线程调度装置,包括启动模块510、监听模块520、判断 模块530、第一处理模块540和第二处理模块550。

启动模块510,用于启动第一线程和第二线程,并使第二线程进入休眠状态。

具体的,进程是程序的基本执行实体,是指令、数据及其组织形式的描述,进程是程序的实体。线程是程序中一个单一的顺序控制流程,是进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派cpu的基本单位及运行中的程序的调度单位。

服务器启动后,可调用pthread_create函数创建第二线程,并将第二线程与第一线程关联,第二线程可专用于处理与第一线程相关的阻塞业务。阻塞是指调用结果返回之前,当前线程会被挂起,即当前线程进入非可执行状态,在这个状态下,cpu不会给该线程分配时间片,该线程暂停运行,函数只有在得到结果之后才会返回。阻塞业务即指会使当前线程进入阻塞状态的客户端请求。第二线程被创建后,可调用pthread_cond_wait函数先令第二线程进入休眠状态,直至第一线程监听到有阻塞业务需要进行处理时,再唤醒第二线程,由第二线程进行处理。将第二线程暂时休眠,等有阻塞业务需要处理时再唤醒,在第二线程的休眠期间节省了cpu的占用,节约了系统资源。

监听模块520,用于通过第一线程监听客户端请求。

具体的,第一线程监听并处理由客户端发送的客户端请求。

判断模块530,用于通过第一线程判断客户端请求是否为同步数据请求。

具体的,同步指的是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,也就是必须一件一件事做,等前一件做完了才能做下一件事。同步数据请求即为该客户端请求需要获取同步数据才可进行处理,例如需要到第三方的mysql服务器上请求相关数据,因mysql服务器只提供同步接口,若要访问mysql的数据,则必须等待直至数据从mysql返回,会造成线程阻塞,即该客户端请求为阻塞业务。

第一处理模块540,用于当第一线程判断出客户端请求不是同步数据请求时,则通过第一线程处理客户端请求,并将处理结果返回客户端。

具体的,若第一线程监听到的客户端请求不是同步数据请求,则表示处理过程中不需要获取同步数据,即为非阻塞业务,则由第一线程直接进行处理, 并将处理结果返回给客户端。

第二处理模块550,用于当第一线程判断出客户端请求是同步数据请求时,则通过第一线程唤醒第二线程,以使第二线程处理该客户端请求,并将处理结果返回客户端。

具体的,当第一线程监听到客户端请求为同步数据请求时,第一线程唤醒第二线程,由第二程处理该客户端请求。第二线程根据该客户端请求获取同步数据进行处理,并将最终处理结果返回客户端。

上述线程调度装置,当第一线程监听到同步数据请求,即当第一线程监听到会造成线程阻塞的客户端请求时,唤醒第二线程,由第二线程处理该客户端请求,可以有效区分阻塞型业务和非阻塞型业务,进而采用不同流程进行处理,能够在减少进程运行中线程切换带来系统开销的同时提高服务器处理客户端请求的速度,有效提高客户端的访问速度,服务器对客户端响应快。

如图6所示,在一个实施例中,上述线程调度装置,第二处理模块550包括获取单元552、存储单元554、唤醒单元556、处理单元558。

获取单元552,用于通过第一线程获取与客户端请求相关的数据。

具体的,当客户端请求为同步数据请求时,第一线程需先获取与该客户端请求相关的数据。与客户端请求相关的数据包括客户端身份标识、第一线程运算结果及所需访问的同步数据等,其中,第一线程运算结果指的是第一线程在之前计算出的与该客户端请求相关的运算结果。

存储单元554,用于将与客户端请求相关的数据存储在预设的数据容器中。

具体的,服务器可预设一个数据容器用于存放与阻塞业务相关的数据,当第一线程监听到客户端请求为同步数据请求时,可将与该客户端请求相关的数据存储在预设的数据容器中,当第二线程被唤醒后,即可从数据容器中读取数据并进行处理。在一个实施例中,存储单元554还用于将与客户端请求相关的数据按照预设的数据格式通过链表的形式存储在预设的数据容器中。例如,预设的数据格式可包括三个内容,内容1为客户端身份标识,内容2为第一线程运算结果,内容3为所需访问的同步数据,一个数据结构表示一个任务,并通过链表的形式进行存储。可以理解地,与客户端请求的数据也可以其它的数据 结构进行存储。当第二线程读取数据容器中的数据时,可按链表上的顺序依次处理数据容器中的任务。

唤醒单元556,用于通过第一线程唤醒第二线程。

具体的,第一线程可通过调用pthread_cond_signal函数唤醒第二线程。

处理单元558,用于通过第二线程读取数据容器的数据,根据读取的数据进行相应处理,并将处理结果返回客户端。

具体的,第二线程被唤醒后,读取数据容器中由第一线程存储的数据,并进行解析,根据处理流程进行处理,最后将处理结果返回客户端。

如图7所示,在一个实施例中,处理单元558包括读取子单元802、获取子单元804、运算子单元806、返回子单元808、移除子单元810和判断子单元812。

读取子单元802,用于通过第二线程读取数据容器中的任务,任务通过预设的数据格式表示。

具体的,如图4所示,数据容器中的数据通过链表的形式存储,链表中的任务通过预设的数据结构表示,数据结构包括三个内容,内容1为客户端身份标识,内容2为第一线程运算结果,内容3为所需访问的同步数据,每个任务代表一个需要获取同步数据的客户端请求。

获取子单元804,用于使第二线程根据任务的所需访问的同步数据从第三方同步接口中获取同步数据。

具体的,第二线程读取数据容器中的任务并解析,可得到任务中数据结构中的内容。第二线程可先根据解析得到的所需访问的同步数据通过第三方同步接口进行访问,并等待第三方将数据返回。例如,所需访问的同步数据为uid100的玩家现在金币的具体数值,则第二线程向mysql服务器发送请求,并等待数据返回,获取所需的同步数据。

运算子单元806,用于使第二线程根据任务的第一线程运算结果及同步数据进行运算。

具体的,第二线程获取到所需的同步数据后,可根据解析得到的第一线程运算结果与同步数据一起进行运算,例如,第一线程运算结果为uid100的玩家通过任务可获得的金币的具体数据为100金币,同步数据为uid100的玩家当前 金币的具体数据为1000金币,通过运算可得到uid100的玩家在任务完成后背包中的金币的具体数值为1100金币。

返回子单元808,用于使第二线程根据任务的客户端身份标识将运算结果返回给客户端。

具体的,第二线程可根据解析得到的客户端身份标识将运算结果返回给对应的客户端,返回成功后即表示该任务处理完成。

移除子单元810,用于将从数据容器中读取并处理的任务从数据容器中移除。

具体的,当任务完成后,可将处理成功的任务从数据容器中移除,避免任务被重覆执行处理。

判断子单元812,用于通过第二线程判断数据容器中是否还有未处理的任务,若是,则使第二线程继续读取数据容器中的任务并处理,若否,则使第二线程进入休眠状态。

具体的,第二线程可查看数据容器中是否还有未处理的任务,若是,则第二线程继续读取并处理数据容器中的任务,直至数据容器中的任务量变为0,例如,如图4中所示,在任务1后还有任务2,则第二线程处理完任务1后还需处理任务2,直至任务被全部处理完。若数据容器中没有未处理的任务,则可重新调用pthread_cond_wait函数使第二线程进入休眠状态,等待下一次有阻塞业务需要处理时再被唤醒。

上述线程调度装置,当第一线程监听到客户端请求为同步数据请求时,可将与该客户端请求相关的数据存储在数据容器中,并唤醒第二线程处理数据容器中的数据,第一线程可继续处理非阻塞业务,由第二线程处理阻塞业务,第一线程与第二线程互不影响,可以有效区分阻塞型业务和非阻塞型业务,进而采用不同流程进行处理,能够在减少进程运行中线程切换带来系统开销的同时提高服务器处理客户端请求的速度,有效提高客户端的访问速度。

以上所述实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技 术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。

以上所述实施例仅表达了本发明的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对发明专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本发明构思的前提下,还可以做出若干变形和改进,这些都属于本发明的保护范围。因此,本发明专利的保护范围应以所附权利要求为准。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1