CN112612581B - 线程主动退出方法和装置 - Google Patents

线程主动退出方法和装置 Download PDF

Info

Publication number
CN112612581B
CN112612581B CN202011403356.1A CN202011403356A CN112612581B CN 112612581 B CN112612581 B CN 112612581B CN 202011403356 A CN202011403356 A CN 202011403356A CN 112612581 B CN112612581 B CN 112612581B
Authority
CN
China
Prior art keywords
thread
function
entry
address
ipc
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Active
Application number
CN202011403356.1A
Other languages
English (en)
Other versions
CN112612581A (zh
Inventor
董广谱
时乐
李蒙
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Beijing Hollysys Co Ltd
Original Assignee
Beijing Hollysys Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Beijing Hollysys Co Ltd filed Critical Beijing Hollysys Co Ltd
Priority to CN202011403356.1A priority Critical patent/CN112612581B/zh
Publication of CN112612581A publication Critical patent/CN112612581A/zh
Application granted granted Critical
Publication of CN112612581B publication Critical patent/CN112612581B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/46Multiprogramming arrangements
    • G06F9/48Program initiating; Program switching, e.g. by interrupt
    • G06F9/4806Task transfer initiation or dispatching
    • G06F9/4843Task transfer initiation or dispatching by program, e.g. task dispatcher, supervisor, operating system
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/46Multiprogramming arrangements
    • G06F9/54Interprogram communication
    • G06F9/542Event management; Broadcasting; Multicasting; Notifications

Landscapes

  • Engineering & Computer Science (AREA)
  • Software Systems (AREA)
  • Theoretical Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Multimedia (AREA)
  • Data Exchanges In Wide-Area Networks (AREA)
  • Facsimiles In General (AREA)

Abstract

本发明公开了线程主动退出方法和装置,该方法包括:当线程将要被激活时,将内核中所述线程的入口地址设置为第一入口函数的地址;所述线程被激活从所述第一入口函数的地址开始运行,所述第一入口函数获取与用户程序对应的第二入口函数的地址,并跳转到所述第二入口函数执行;当从第二入口函数返回到第一入口函数时,第一入口函数删除所述线程。本发明提供的方法和装置在用户空间实现线程主动退出功能。

Description

线程主动退出方法和装置
技术领域
本公开涉及计算机技术领域,尤其涉及线程主动退出方法和装置。
背景技术
PLC控制器广泛应用于过程控制领域,提高PLC控制器的安全性意义重大。和利时公司基于国产MIPS架构处理器研发了高安全的微内核操作系统内核(简称微内核),该微内核运行在操作系统的内核空间。和利时公司基于该微内核开发了PLC控制器软件,该PLC控制器软件运行在操作系统的用户空间。
根据PLC控制器软件需求,PLC必须提供一种防御机制,该防御机制可以保证当用户的IEC线程意外退出时微内核操作系统不崩溃。该需求的本质是必须实现线程主动退出功能,保证线程主动退出时微内核操作系统不崩溃。线程主动退出功能通常运行在内核空间(由内核实现),例如linux、vxworks等。该微内核在内核空间只提供线程管理、进程间通信(IPC)、虚拟内存空间、句柄空间、设备基础单元(中断对象)五项极其原始的功能,没有实现线程主动退出功能。
发明内容
本公开实施例提供了一种线程主动退出方法,包括:
当线程将要被激活时,将内核中所述线程的入口地址设置为第一入口函数的地址;
所述线程被激活从所述第一入口函数的地址开始运行,所述第一入口函数获取与用户程序对应的第二入口函数的地址,并跳转到所述第二入口函数执行;
当从第二入口函数返回到第一入口函数时,第一入口函数删除所述线程。
一种示例性的实施例中,当从第二入口函数返回到第一入口函数时,第一入口函数删除所述线程,包括:
当所述第二入口函数的地址有效时,所述线程从所述第二入口函数的地址开始运行第二入口函数;当满足预设条件需要返回时,所述线程返回到所述第一入口函数并由所述第一入口函数删除所述线程;
当所述第二入口函数的地址无效时,所述线程返回到所述第一入口函数并由所述第一入口函数删除所述线程。
一种示例性的实施例中,当线程将要被激活时,将内核中所述线程的入口地址设置为第一入口函数的地址,包括:
当线程激活函数被调用时,触发与所述线程激活函数对应的处理函数根据所述线程的标识id将内核中所述线程的入口地址设置为第一入口函数的地址;其中,所述线程激活函数被调用时携带所述线程的id。
一种示例性的实施例中,当线程激活函数被调用时,触发与所述线程激活函数对应的处理函数根据所述线程的id将内核中所述线程的入口地址设置为第一入口函数的地址,包括:
当线程激活函数被调用后,生成IPC消息并将所述IPC消息发送给管理线程并阻塞自身;所述IPC消息包括消息标志和消息内容;所述消息内容为所述线程的id;
所述管理线程接收到所述IPC消息后,根据所述IPC消息的消息标志确定线程激活函数对应的处理函数为线程激活处理函数,并调用所述线程激活处理函数;
所述线程激活处理函数根据所述线程的id将内核中所述线程的入口地址设置为第一入口函数的地址后,构建IPC应答消息返回给所述线程激活函数;
当所述线程激活函数收到IPC应答后返回到调用方。
一种示例性的实施例中,所述线程激活处理函数执行相应处理后,构建IPC应答消息返回给所述线程激活函数,包括:
所述线程激活处理函数从所述IPC消息中解析出所述线程的id;
根据所述线程的id找到记录所述线程的结构体;
从所述线程的结构体中找到所述线程的句柄;
设置临时变量为所述第一入口函数的地址;
根据所述句柄修改内核中所述线程的入口地址为所述临时变量;
构建包括修改结果的IPC应答并发送给线程激活函数。
一种示例性的实施例中,所述第一入口函数获取与用户程序对应的第二入口函数的地址,包括:
所述第一入口函数通过调用获取线程id的接口函数获得所述线程的id;
根据所述线程的id通过调用获取线程入口的接口函数获取所述第二入口函数的地址。
一种示例性的实施例中,根据所述线程的id通过调用获取线程入口的接口函数获取所述第二入口函数的地址,包括:
当获取线程入口的接口函数被调用后,生成IPC消息并将所述IPC消息发送给管理线程并阻塞自身;所述IPC消息包括消息标志和消息内容;所述消息内容包括所述线程的id;
所述管理线程接收到IPC消息后,根据所述IPC消息的消息标志确定获取线程入口的接口函数的实现函数;并调用获取线程入口的接口函数的实现函数;
所述获取线程入口的接口函数的实现函数从所述IPC消息中解析出所述线程的id;
根据所述线程的id调用用于查找线程的内部子函数;
所述用于查找线程的内部子函数的返回记录所述线程的结构体;
根据所述线程的结构体查找所述线程的第二入口函数的地址;
构建包括所述线程的第二入口函数的地址的IPC应答返回给所述获取线程入口的接口函数;
所述获取线程入口的接口函数收到IPC应答后,解析出所述线程的第二入口函数的地址并赋值给第二入口函数。
一种示例性的实施例中,所述第一入口函数删除所述线程,包括:
所述第一入口函数调用用于获取线程IPC的接口函数获取到所述线程的ipc地址;
根据所述线程的ipc地址调用线程主动退出函数删除所述线程。
一种示例性的实施例中,根据所述线程的ipc地址调用线程主动退出函数删除所述线程,包括:
当所述线程主动退出函数被调用时,生成IPC消息并将所述IPC消息发送给管理线程并阻塞自身;所述IPC消息包括消息标志和消息内容;所述消息内容为所述线程的ipc地址;
所述管理线程接收到IPC消息后,根据所述IPC消息的消息标志确定线程主动退出函数对应的处理函数为线程主动退出函数的处理函数;并调用线程主动退出函数的处理函数;
所述线程主动退出函数的处理函数执行相应处理后,构建IPC应答消息返回给所述线程主动退出函数。
一种示例性的实施例中,所述线程主动退出函数的处理函数执行相应处理后,构建IPC应答消息返回给所述线程主动退出函数,包括:
所述线程主动退出函数的处理函数从所述IPC消息中解析所述线程的ipc地址;
调用用于通过ipc地址线程的内部子函数;
接收返回的记录线程信息的结构体;
根据记录线程信息的结构体找到线程的句柄;
调用用于线程挂起的接口函数,将线程挂起;
调用用于线程清除的接口函数,将线程从内核中清除。
本公开还提供了一种线程主动退出装置,包括:存储器和处理器;
所述存储器,用于保存用于线程主动退出的程序;
所述处理器,用于读取并执行上述用于线程主动退出的程序。
本公开实施例提供的线程主动退出方法和装置,通过将内核中线程的入口地址设置为第一入口函数的地址,所述线程被激活从所述第一入口函数的地址开始运行,所述第一入口函数获取与用户程序对应的第二入口函数的地址,并跳转到所述第二入口函数执行;当从第二入口函数返回到第一入口函数时,第一入口函数删除所述线程,从而在用户空间实现了线程的主动退出功能,解决了线程退出引起的微内核操作系统崩溃问题。
附图说明
图1为本公开实施例的线程主动退出方法的示意图。
图2为本公开实施例的PLC控制器结构框图。
图3为本公开实施例的获取线程用户入口流程图。
图4为本公开实施例的线程主动退出流程图。
图5为本公开实施例的后台入口函数流程图。
图6为本公开实施例的线程激活流程图。
图7为本公开实施例的线程主动退出装置的示意图。
具体实施方式
下文中将结合附图对本公开的实施例进行详细说明。需要说明的是,在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互任意组合。
图1为本公开实施例的线程主动退出方法的示意图,如图1所示,本实施例的线程主动退出方法包括:
S11、当线程将要被激活时,将内核中所述线程的入口地址设置为第一入口函数的地址。
S12、所述线程被激活从所述第一入口函数的地址开始运行,所述第一入口函数获取与用户程序对应的第二入口函数的地址,并跳转到所述第二入口函数执行。
S13、当从第二入口函数返回到第一入口函数时,第一入口函数删除所述线程。
一种示例性的实施例中,当线程将要被激活时,即,用户调用激活线程的接口函数os_api_task_activate时。
一种示例性的实施例中,第一入口函数可以为统一的后台入口函数os_inner_task_sys_entry。
一种示例性的实施例中,第二入口函数可以为用户设置的程序的真正入口函数,例如entryPt。
一种示例性的实施例中,当从第二入口函数返回到第一入口函数时,第一入口函数删除所述线程,包括:
当所述第二入口函数的地址有效时,所述线程从所述第二入口函数的地址开始运行第二入口函数;当满足预设条件需要返回时,所述线程返回到所述第一入口函数并由所述第一入口函数删除所述线程;
当所述第二入口函数的地址无效时,所述线程返回到所述第一入口函数并由所述第一入口函数删除所述线程。
一种示例性的实施例中,当线程将要被激活时,将内核中所述线程的入口地址设置为第一入口函数的地址,包括:
当线程激活函数被调用时,触发与所述线程激活函数对应的处理函数根据所述线程的标识id将内核中所述线程的入口地址设置为第一入口函数的地址;其中,所述线程激活函数被调用时携带所述线程的id。
一种示例性的实施例中,当线程激活函数被调用时,触发与所述线程激活函数对应的处理函数根据所述线程的id将内核中所述线程的入口地址设置为第一入口函数的地址,包括:
当线程激活函数被调用后,生成IPC消息并将所述IPC消息发送给管理线程并阻塞自身;所述IPC消息包括消息标志和消息内容;所述消息内容为所述线程的id;
所述管理线程接收到所述IPC消息后,根据所述IPC消息的消息标志确定线程激活函数对应的处理函数为线程激活处理函数,并调用所述线程激活处理函数;
所述线程激活处理函数根据所述线程的id将内核中所述线程的入口地址设置为第一入口函数的地址后,构建IPC应答消息返回给所述线程激活函数;
当所述线程激活函数收到IPC应答后返回到调用方。
其中,IPC消息为进程间通信消息。
一种示例性的实施例中,所述线程激活处理函数执行相应处理后,构建IPC应答消息返回给所述线程激活函数,包括:
所述线程激活处理函数从所述IPC消息中解析出所述线程的id;
根据所述线程的id找到记录所述线程的结构体;
从所述线程的结构体中找到所述线程的句柄;
设置临时变量为所述第一入口函数的地址;
根据所述句柄修改内核中所述线程的入口地址为所述临时变量;
构建包括修改结果的IPC应答并发送给线程激活函数。
一种示例性的实施例中,所述第一入口函数获取与用户程序对应的第二入口函数的地址,包括:
所述第一入口函数通过调用线程id获取函数获得所述线程的id;
根据所述线程的id通过调用获取线程入口的接口函数获取所述第二入口函数的地址。
其中,线程id获取函数可以为用于获取线程id的函数。例如,os_api_task_get_id()。
获取线程入口的接口函数可以为用于获取用户设置的程序的入口函数的地址。例如,os_api_task_get_entry(iTaskId,&entryPt),iTaskId为线程的id,&entryPt为线程的真正入口entryPt的地址。
一种示例性的实施例中,根据所述线程的id通过调用获取线程入口的接口函数获取所述第二入口函数的地址,包括:
当获取线程入口的接口函数被调用后,生成IPC消息并将所述IPC消息发送给管理线程并阻塞自身;所述IPC消息包括消息标志和消息内容;所述消息内容包括所述线程的id;
所述管理线程接收到IPC消息后,根据所述IPC消息的消息标志确定获取线程入口的接口函数的实现函数;并调用获取线程入口的接口函数的实现函数;
所述获取线程入口的接口函数的实现函数从所述IPC消息中解析出所述线程的id;
根据所述线程的id调用用于查找线程的内部子函数;
所述用于查找线程的内部子函数的返回记录所述线程的结构体;
根据所述线程的结构体查找所述线程的第二入口函数的地址;
构建包括所述线程的第二入口函数的地址的IPC应答返回给所述获取线程入口的接口函数;
所述获取线程入口的接口函数收到IPC应答后,解析出所述线程的第二入口函数的地址并赋值给第二入口函数。
一种示例性的实施例中,所述第一入口函数删除所述线程,包括:
所述第一入口函数调用用于获取线程IPC的接口函数获取到所述线程的ipc地址;
根据所述线程的ipc地址调用线程主动退出函数删除所述线程。
其中,ipc地址为进程间通讯地址。
一种示例性的实施例中,根据所述线程的ipc地址调用线程主动退出函数删除所述线程,包括:
当所述线程主动退出函数被调用时,生成IPC消息并将所述IPC消息发送给管理线程并阻塞自身;所述IPC消息包括消息标志和消息内容;所述消息内容为所述线程的ipc地址;
所述管理线程接收到IPC消息后,根据所述IPC消息的消息标志确定线程主动退出函数对应的处理函数为线程主动退出函数的处理函数;并调用线程主动退出函数的处理函数;
所述线程主动退出函数的处理函数执行相应处理后,构建IPC应答消息返回给所述线程主动退出函数。
一种示例性的实施例中,所述线程主动退出函数的处理函数执行相应处理后,构建IPC应答消息返回给所述线程主动退出函数,包括:
所述线程主动退出函数的处理函数从所述IPC消息中解析所述线程的ipc地址;
调用用于通过ipc地址查找线程的内部子函数;
接收返回的记录线程信息的结构体;
根据记录线程信息的结构体找到线程的句柄;
调用用于线程挂起的接口函数,将线程挂起;
调用用于线程清除的接口函数,将线程从内核中清除。
其中,由于每个线程的ipc地址都是唯一的,只需要查找全部线程的ipc地址就可查找到对应的线程。查找线程的内部子函数用于通过ipc地址查找到对应的线程。
通过本公开的实施例在用户空间实现了线程的主动退出功能,解决了线程退出引起的微内核操作系统崩溃问题。
下面结合另一实施例——基于微内核操作系统的PLC控制器的线程主动退出功能实现方法来说明在用户空间实现的线程的主动退出功能。
在没有添加线程主动退出功能的时候,用户调用os_api_task_activate激活一个线程,要激活的线程直接从用户设置的入口函数开始执行。如果该入口函数执行了return或者意外返回,微内核本身没办法拦截,要激活的线程将返回到一个非法地址继续执行,从而引起微内核操作系统崩溃。
基于微内核操作系统的PLC控制器的线程主动退出功能实现方法主要修改了管理线程和软件接口两部分。其中管理线程对应图2PLC控制器结构框图之部件18管理线程,软件接口对应图2PLC控制器结构框图之部件22软件接口。本公开实施例的线程主动退出功能实现方法所涉及的管理线程和软件接口两部分,全部运行在用户空间。本公开实施例在管理线程和软件接口两部分增加了一组函数集,如下所示:
1、os_api_task_get_entry(隶属于软件接口,即上文中的获取线程入口的接口函数)、os_lib_task_get_entry(隶属于管理线程,即上文中的获取线程入口的接口函数的实现函数);
2、os_api_task_exit(隶属于软件接口,即上文中的线程主动退出函数)、os_lib_task_exit(隶属于管理线程,即上文中的线程主动退出函数的处理函数);
3、os_inner_task_sys_entry(隶属于软件接口,即上文中的第一入口函数);
4、os_api_task_active(隶属于软件接口,即上文中的线程激活函数)、os_lib_task_active(隶属于管理线程,即上文中的线程激活处理函数);
本公开实施例的线程主动退出功能实现方法为:
(1)用户调用os_api_task_activate,参数为要激活的线程(记为threadZ)的iTaskId。
(2)os_api_task_activate触发os_lib_task_activate执行。该函数调用os_TCB_WriteRegisters。os_TCB_WriteRegisters函数设置内核中threadZ的入口地址为os_inner_task_sys_entry。设置完毕入口地址后,threadZ线程就处于可运行状态。
(3)当threadZ运行时,threadZ从os_inner_task_sys_entry函数开始执行。
(4)os_inner_task_sys_entry首先调用os_api_task_get_id()(即上文中的获取线程id的接口函数)获得当前线程的iTaskId。然后调用os_api_task_get_entry(iTaskId,&entryPt),得到用户设置的入口函数entryPt。接着跳转到entryPt执行真正的用户程序逻辑。
(5)在绝大多数情况下,entryPt所对应的用户程序逻辑都是一个死循环,会一直执行,不会退出,也就是不会返回到os_inner_task_sys_entry。
(6)本公开实施例中,如果用户程序因为设计错误意外退出了while循环,将返回到os_inner_task_sys_entry;如果用户程序调用return主动退出while循环,将返回到os_inner_task_sys_entry;
(7)如果entryPt返回,os_inner_task_sys_entry将调用os_api_task_exit()。调用os_api_task_exit()后,线程threadZ被管理线程彻底删除。
综上所述,os_inner_task_sys_entry成功拦截了entryPt中的意外退出和主动退出,并调用os_api_task_exit实现线程threadZ的销毁,从而避免了微内核操作系统崩溃。
本公开实施例的os_api_task_get_entry和os_lib_task_get_entry,函数逻辑如图3获取线程用户入口流程图所示。
本公开实施例的os_api_task_get_entry是获取线程入口函数的接口函数。该函数隶属于软件接口。该函数由os_inner_task_sys_entry调用。该函数原型如下:
int os_api_task_get_entry(int iTaskId,unsigned int*entryPt);
当调用方调用os_api_task_get_entry时将生成一个IPC消息。该IPC消息标志为OS_API_TASKENTRYGET(=101),该IPC消息内容为:iTaskId(线程id)。之后os_api_task_get_entry调用CallWithMRs发送该IPC消息给管理线程,并被阻塞直到收到应答。
管理线程一直在等待IPC消息并阻塞。当管理线程收到该IPC消息后开始执行。管理线程解析消息标志判断出这是OS_API_TASKENTRYGET(=101)消息,该消息对应的子处理函数是os_lib_task_get_entry,该函数的流程为:
(1)从IPC消息中解析出iTaskId(线程id);
(2)调用函数inner_lookup_task_by_id(即上文中的获取线程id的接口函数),该函数根据iTaskId找到记录该线程信息的结构体;
(3)从记录该线程信息的结构体中,找到该线程的用户设置的入口函数。备注:该入口函数是用户调用os_api_task_create时传参并保存的,本专利对os_api_task_create无修改;
(4)构建IPC应答(包含该线程的入口函数指针),并发送给os_api_task_get_entry;
(5)当发送完IPC应答后,管理线程开始阻塞并等待下一个IPC消息。
当os_api_task_get_entry收到IPC应答时,从中解析出该线程的入口函数指针,赋给entryPt,随后返回到调用方。
本公开实施例的os_api_task_exit和os_lib_task_exit,函数逻辑如图5线程主动退出流程图所示。
本公开实施例的os_api_task_exit,是实现线程主动退出的接口函数。该函数隶属于软件接口。该函数由os_inner_task_sys_entry调用。该函数原型如下:
void os_api_task_exit();
当调用方调用os_api_task_exit时,os_api_task_exit函数首先调用os_GetThreadIPC()(即上文中的用于获取线程IPC的接口函数)获得当前线程的ipcAddr(ipc地址)。os_api_task_exit函数然后生成一个IPC消息。该IPC消息标志为OS_API_TASKDELSELF(=110),该IPC消息内容为:ipcAddr。之后os_api_task_exit调用CallWithMRs发送该IPC消息给管理线程。
管理线程一直在等待IPC消息并阻塞。当管理线程收到该IPC消息后开始执行。管理线程解析消息标志判断出这是OS_API_TASKDELSELF(=110)消息,该消息对应的子处理函数是os_lib_task_exit,该函数的流程为:
(1)从IPC消息中解析出ipcAddr;
(2)调用函数inner_lookup_task_by_ipc_addr(即上文中的用于通过ipc地址查找线程的内部子函数),该函数根据ipcAddr找到记录该线程信息的结构体;
(3)从记录该线程信息的结构体中,找到该线程的句柄cptr;
(4)调用os_TCB_Suspend(cptr)(即上文中的用于线程挂起的接口函数),将该线程挂起;
(5)调用os_thread_cleanup(即上文中的用于线程清除的接口函数),释放该线程持有的全部内存资源,将该线程从微内核中彻底清除干净。
(6)之后管理线程开始阻塞并等待下一个IPC消息。
调用os_api_task_exit的线程发送了OS_API_TASKDELSELF(=110)消息,该线程在上述第(5)步中被彻底删除。所以调用os_api_task_exit的线程,在调用了os_api_task_exit后已经不存在了,再也不会返回了。与此同时管理线程也无法向其发送IPC应答了。
本公开实施例的os_inner_task_sys_entry,函数逻辑如图5线程后台入口函数流程图所示。
os_inner_task_sys_entry是根据微内核操作系统的特点设计的线程后台入口函数,该函数是实现线程主动退出的最关键函数。该函数隶属于软件接口,该函数只能由os_lib_task_active使用,其它地方禁止使用。该函数原型如下:
void os_inner_task_sys_entry();
该函数的主要逻辑为:
(1)调用os_api_task_get_id()获得当前线程的iTaskId
(2)调用前述os_api_task_get_entry(iTaskId,&entryPt),得到线程的真正入口entryPt;
(3)如果线程的entryPt是有效指针,就跳转到entryPt所指的地址执行;
(4)如果entryPt返回,就调用前述os_api_task_exit(),实现当前线程的挂起和资源删除。调用os_api_task_exit()后,该线程被管理线程彻底删除,再不返回。
本公开实施例的os_api_task_active和os_lib_task_active,函数逻辑如图6线程激活流程图所示。
本公开实施例的os_api_task_active,是实现线程激活的接口函数。该函数隶属于软件接口。该函数由用户程序调用,用于激活图2中PLC控制器结构框图之部件26IEC运算线程等多个线程。该函数原型如下:int os_api_task_activate(int iTaskId);
需要特别说明的是,os_api_task_activate的参数iTaskId指的是将要激活的线程的iTaskId,不是调用方所在线程的iTaskId。当调用方调用os_api_task_activate后,参数iTaskId所代表的线程将被微内核激活和运行。
当调用方调用os_api_task_active时将生成一个IPC消息。该IPC消息标志为OS_API_TASKACTIVATE(=8),该IPC消息内容为:iTaskId(将要激活的线程的线程id)。之后os_api_task_active调用CallWithMRs发送该IPC消息给管理线程,并被阻塞直到收到应答。
管理线程一直在等待IPC消息并阻塞。当管理线程收到该IPC消息后开始执行。管理线程解析消息标志判断出这是OS_API_TASKACTIVATE(=8)消息,该消息对应的子处理函数是os_lib_task_activate,该函数的流程为:
(1)从IPC消息中解析出iTaskId(线程id);
(2)调用函数inner_lookup_task_by_id(即,根据id查找线程的内部子函数),该函数根据iTaskId找到记录该线程信息的结构体;
(3)从记录该线程信息的结构体中,找到该线程的句柄cptr;
(4)令临时变量pFunAddr=os_inner_task_sys_entry,即pFunAddr等于前面所述后台入口函数的地址;
(5)调用os_TCB_WriteRegisters(cptr,pFunAddr),强制修改微内核中将要激活的线程的入口地址为pFunAddr,即os_inner_task_sys_entry,也就是强制微内核从一个统一的后台入口函数os_inner_task_sys_entry开始执行程序逻辑。
结合前述os_inner_task_sys_entry的分析可知,该函数可以根据实际执行的上下文自动判断出用户设定的线程入口函数,并跳转到用户设定的线程入口函数执行。
(6)构建IPC应答并发送给os_api_task_active;
(7)当发送完IPC应答后,管理线程开始阻塞并等待下一个IPC消息。
当os_api_task_active收到IPC应答时,返回到调用方。
本公开实施例在位于用户空间的管理线程和软件接口两部分中增加了一组函数集,该函数集紧密配合完成了线程主动退出功能,该函数集全部运行在用户空间。本公开实施例为用户线程设计了一个统一的后台入口函数以替代用户设定的入口函数,从根本上解决了线程退出引起的微内核操作系统崩溃问题,实现了PLC控制器的线程主动退出功能。
图7为本公开实施例的线程主动退出装置的示意图,如图7所示,本实施例的线程主动退出装置包括:存储器和处理器;
所述存储器,用于保存用于线程主动退出的程序;
所述处理器,用于读取并执行如上所述用于线程主动退出的程序。
本领域普通技术人员可以理解上述方法中的全部或部分步骤可通过程序来指令相关硬件完成,所述程序可以存储于计算机可读存储介质中,如只读存储器、磁盘或光盘等。可选地,上述实施例的全部或部分步骤也可以使用一个或多个集成电路来实现。相应地,上述实施例中的各模块/单元可以采用硬件的形式实现,也可以采用软件功能模块的形式实现。本公开不限制于任何特定形式的硬件和软件的结合。
以上仅为本公开的优选实施例,当然,本公开还可有其他多种实施例,在不背离本公开精神及其实质的情况下,熟悉本领域的技术人员当可根据本公开作出各种相应的改变和变形,但这些相应的改变和变形都应属于本公开所附的权利要求的保护范围。

Claims (8)

1.一种线程主动退出方法,包括:
当线程将要被激活时,将内核中所述线程的入口地址设置为第一入口函数的地址;
所述线程被激活从所述第一入口函数的地址开始运行,所述第一入口函数获取与用户程序对应的第二入口函数的地址,并跳转到所述第二入口函数执行;
当从第二入口函数返回到第一入口函数时,第一入口函数删除所述线程;
其中,所述第一入口函数删除所述线程,包括:
所述第一入口函数调用用于获取线程IPC的接口函数获取到所述线程的ipc地址;
根据所述线程的ipc地址调用线程主动退出函数删除所述线程;
根据所述线程的ipc地址调用线程主动退出函数删除所述线程,包括:
当所述线程主动退出函数被调用时,生成IPC消息并将所述IPC消息发送给管理线程并阻塞自身;所述IPC消息包括消息标志和消息内容;所述消息内容为所述线程的ipc地址;
所述管理线程接收到IPC消息后,根据所述IPC消息的消息标志确定线程主动退出函数对应的处理函数为线程主动退出函数的处理函数;并调用线程主动退出函数的处理函数;
所述线程主动退出函数的处理函数执行相应处理后,构建IPC应答消息返回给所述线程主动退出函数;
所述线程主动退出函数的处理函数执行相应处理后,构建IPC应答消息返回给所述线程主动退出函数,包括:
所述线程主动退出函数的处理函数从所述IPC消息中解析所述线程的ipc地址;
调用用于通过ipc地址查找线程的内部子函数;
接收返回的记录线程信息的结构体;
根据记录线程信息的结构体找到线程的句柄;
调用用于线程挂起的接口函数,将线程挂起;
调用用于线程清除的接口函数,将线程从内核中清除。
2.如权利要求1所述的方法,当从第二入口函数返回到第一入口函数时,第一入口函数删除所述线程,包括:
当所述第二入口函数的地址有效时,所述线程从所述第二入口函数的地址开始运行第二入口函数;当满足预设条件需要返回时,所述线程返回到所述第一入口函数并由所述第一入口函数删除所述线程;
当所述第二入口函数的地址无效时,所述线程返回到所述第一入口函数并由所述第一入口函数删除所述线程。
3.如权利要求1所述的方法,当线程将要被激活时,将内核中所述线程的入口地址设置为第一入口函数的地址,包括:
当线程激活函数被调用时,触发与所述线程激活函数对应的处理函数根据所述线程的标识id将内核中所述线程的入口地址设置为第一入口函数的地址;其中,所述线程激活函数被调用时携带所述线程的id。
4.如权利要求3所述的方法,当线程激活函数被调用时,触发与所述线程激活函数对应的处理函数根据所述线程的id将内核中所述线程的入口地址设置为第一入口函数的地址,包括:
当线程激活函数被调用后,生成IPC消息并将所述IPC消息发送给管理线程并阻塞自身;所述IPC消息包括消息标志和消息内容;所述消息内容为所述线程的id;
所述管理线程接收到所述IPC消息后,根据所述IPC消息的消息标志确定线程激活函数对应的处理函数为线程激活处理函数,并调用所述线程激活处理函数;
所述线程激活处理函数根据所述线程的id将内核中所述线程的入口地址设置为第一入口函数的地址后,构建IPC应答消息返回给所述线程激活函数;
当所述线程激活函数收到IPC应答后返回到调用方。
5.如权利要求4所述的方法,所述线程激活处理函数执行相应处理后,构建IPC应答消息返回给所述线程激活函数,包括:
所述线程激活处理函数从所述IPC消息中解析出所述线程的id;
根据所述线程的id找到记录所述线程的结构体;
从所述线程的结构体中找到所述线程的句柄;
设置临时变量为所述第一入口函数的地址;
根据所述句柄修改内核中所述线程的入口地址为所述临时变量;
构建包括修改结果的IPC应答并发送给线程激活函数。
6.如权利要求1所述的方法,所述第一入口函数获取与用户程序对应的第二入口函数的地址,包括:
所述第一入口函数通过调用获取线程id的接口函数获得所述线程的id;
根据所述线程的id通过调用获取线程入口的接口函数获取所述第二入口函数的地址。
7.如权利要求6所述的方法,根据所述线程的id通过调用获取线程入口的接口函数获取所述第二入口函数的地址,包括:
当获取线程入口的接口函数被调用后,生成IPC消息并将所述IPC消息发送给管理线程并阻塞自身;所述IPC消息包括消息标志和消息内容;所述消息内容包括所述线程的id;
所述管理线程接收到IPC消息后,根据所述IPC消息的消息标志确定获取线程入口的接口函数的实现函数;并调用获取线程入口的接口函数的处理函数;
所述获取线程入口的接口函数的实现函数从所述IPC消息中解析出所述线程的id;
根据所述线程的id调用用于查找线程的内部子函数;
所述用于查找线程的内部子函数的返回记录所述线程的结构体;
根据所述线程的结构体查找所述线程的第二入口函数的地址;
构建包括所述线程的第二入口函数的地址的IPC应答返回给所述获取线程入口的接口函数;
所述获取线程入口的接口函数收到IPC应答后,解析出所述线程的第二入口函数的地址并赋值给第二入口函数。
8.一种线程主动退出装置,包括:存储器和处理器;其特征在于:
所述存储器,用于保存用于线程主动退出的程序;
所述处理器,用于读取并执行如权利要求1-7中任一项所述用于线程主动退出的程序。
CN202011403356.1A 2020-12-02 2020-12-02 线程主动退出方法和装置 Active CN112612581B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202011403356.1A CN112612581B (zh) 2020-12-02 2020-12-02 线程主动退出方法和装置

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202011403356.1A CN112612581B (zh) 2020-12-02 2020-12-02 线程主动退出方法和装置

Publications (2)

Publication Number Publication Date
CN112612581A CN112612581A (zh) 2021-04-06
CN112612581B true CN112612581B (zh) 2024-02-13

Family

ID=75228801

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202011403356.1A Active CN112612581B (zh) 2020-12-02 2020-12-02 线程主动退出方法和装置

Country Status (1)

Country Link
CN (1) CN112612581B (zh)

Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2010022635A1 (zh) * 2008-09-01 2010-03-04 中兴通讯股份有限公司 多线程通讯程序中防止线程吊死的方法
CN102222015A (zh) * 2010-04-13 2011-10-19 三星电子(中国)研发中心 检测多线程程序中的死锁的方法及系统
CN111258684A (zh) * 2020-01-22 2020-06-09 北京和利时系统工程有限公司 一种控制方法和装置

Family Cites Families (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6952827B1 (en) * 1998-11-13 2005-10-04 Cray Inc. User program and operating system interface in a multithreaded environment
CN102750157A (zh) * 2011-04-20 2012-10-24 中兴通讯股份有限公司 一种应用程序加载的方法及装置

Patent Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2010022635A1 (zh) * 2008-09-01 2010-03-04 中兴通讯股份有限公司 多线程通讯程序中防止线程吊死的方法
CN102222015A (zh) * 2010-04-13 2011-10-19 三星电子(中国)研发中心 检测多线程程序中的死锁的方法及系统
CN111258684A (zh) * 2020-01-22 2020-06-09 北京和利时系统工程有限公司 一种控制方法和装置

Non-Patent Citations (1)

* Cited by examiner, † Cited by third party
Title
嵌入式操作系统的多线程机制研究与实现;陈雪芳;;电脑知识与技术(07);全文 *

Also Published As

Publication number Publication date
CN112612581A (zh) 2021-04-06

Similar Documents

Publication Publication Date Title
US6826746B2 (en) Debugger probe for object oriented programming
KR100326745B1 (ko) 통합오토메이션개발시스템및그통합방법
US8893222B2 (en) Security system and method for the android operating system
JP3095777B2 (ja) オブジェクト指向オペレーティング・システム
JP4676744B2 (ja) セキュリティ関連プログラミング・インターフェース
US7614059B2 (en) System and method for the discovery and usage of local resources by a mobile agent object
US8448165B1 (en) System and method for logging operations of virtual machines
KR100645983B1 (ko) 불법 프로세스 검출 모듈 및 그 방법
US20080148355A1 (en) Providing Policy-Based Operating System Services in an Operating System on a Computing System
US6584487B1 (en) Method, system, and apparatus for managing tasks
US11269663B2 (en) Method and apparatus for adapting handle device to third-party application, and storage medium
US7552434B2 (en) Method of performing kernel task upon initial execution of process at user level
CN115335806A (zh) 以模块粒度的影子堆栈违规强制
US7546600B2 (en) Method of assigning virtual process identifier to process within process domain
US7617487B2 (en) Method and system for debugging individual threads in a productive environment
US6256752B1 (en) Method and apparatus for dynamic swappable bytecode loop in java virtual machines
CN112612581B (zh) 线程主动退出方法和装置
US7962922B2 (en) Delivering callbacks into secure application areas
CN111258684B (zh) 一种控制方法和装置
JP2004094374A (ja) ロギングシステム
CN116956272A (zh) 权限调用监控方法、装置及电子设备
Mostinckx et al. Mirages: Behavioral intercession in a mirror-based architecture
CN114816668A (zh) 一种虚拟机内核监测方法、装置、设备及存储介质
CN115220859A (zh) 数据输入方式的监测方法、装置、电子设备和存储介质
CN108023966B (zh) 通用网关接口请求处理方法、设备和存储介质

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant