现在的位置: 首页 > 综合 > 正文

与RTX相关的进程与线程基础知识

2013年02月18日 ⁄ 综合 ⁄ 共 9167字 ⁄ 字号 评论关闭
文章目录

进程与线程

进程由地址空间(address space),目标句柄(object handles),一条以上可执行的线程(threads)。线程多用于响应中断,或用来同步事件(handle asynchronous process-related events in thread context)。RTSS的进程与线程函数与Win32下的很相似。但是RTSS和Win32下的进程或者线程仅能在自己的环境中运行,不能相互访问。(RTSS and Win32 processes and threads can access
processes and threads only within their own environment.,原文中是这样一句话,不知道自己理解的是否正确,但是就现实来看,Win32进程和RTSS进程之间可以通过共享内存来实现数据交换,那么这种情况就和文档中所描述的是矛盾的,以后有进一步理解后可以对这段东西进行修正)。

Win32进程与RTSS进程之间的关系可以用以下一张图来进行表述:

以下描述会大量饮用英文原文,对于重要的地方会用汉语进行注解

RTSS环境下的进程:

A process running in the RTSS environment consists of a set of
handles to objects
, process address space,at least one thread, andan executable(这个executable应该指一段可执行程序. When
a process is created, RTSS performs the following tasks:

  • Loads the executable as a driver

  • Allocates process heap from the non-paged pool

  • Creates the primary thread

A process can be started by either one of these methods:

  • Loading it as a device driver during system boot (using the RTSSrun /b utility)

  • Running the RTSS executable from the command line

  • Starting the RTSS process from Win32 applications(这种方案是最实用,最常用的方案)

A process exits under one of these conditions:

  • The last thread has exited(这种情况我也遇到过,当主进程关闭时,所有的定时器进程也就关闭了)

  • One thread calls ExitProcess

  • The process is killed with the
    RTSSkill utility or the RTSS Task Manager(开始->Adrence->RTX->Tools->Rtss Task Managers)

The maximum number of processes that can exist concurrently in the RTSS environment is equal to the number of RTSS process slots in the registry (the default is 10).

其设置的位置如下图所示:

Win32环境下的进程:

A process running in the Win32 environment starts interacting with RTX when it makes an RTAPI call. RTX then may allocate resources for this process, alter its priorities, and perform other operations related to its Win32
process status. The number of Win32 processes that can interact with RTX is dynamic; it depends on your system's configuration and resources.

 

Using Threads

The CreateThread function createseither an RTSS or a Win32 thread, depending on the current execution environment of the process. You can specify the stack size
of subsequently created threads of that process usingCreateThread. The returned handle and thread ID are valid only in theCreateThread caller's
environment. For instance, a Win32 process cannot manipulate the priority of an RTSS thread because the handle for the thread is valid only in the RTSS environment. You can, however, use the RTX Interprocess Communication (IPC) mechanisms (such asmutex
objects
,semaphores, events, andshared memory) tosynchronize and communicate between Win32 and RTSS processes and threads.(传说中的线程同步机制)

Timer and Interrupt Objects

Timer and interrupt objects derive from the threads; therefore, the handles for these objects are valid only in their own (Win32 or RTSS) environment. Similarly, these objects can be manipulated only by processes in their own environment.

RTSS Environment

An RTSS thread is the unit of execution in the RTSS environment. A ready-to-run RTSS thread is scheduled before all Windows threads.(因为rtss比windows优先级高,会抢占硬件资源,所以RTSS的进程或者线程会优先进行) An RTSS thread runs until it gives up the
CPU. A thread gives up the CPU when it:

  • Waits for a synchronization object(等待同步)

  • Lowers its own priority or raises another thread's priority(降低自己的优先级或者提升其它进程的优先级)

  • Suspends itself(将自己挂起)

  • Returns from the timer or interrupt handler (applicable to timer and interrupt threads) routines(执行完毕一个定制器或者中断的响应程序)

  • Calls Sleep with an argument of 0()

  • Receives a notification that a time quantum is set

  • Is interrupted by a higher priority

The initial thread of a process has an 8 KB stack.

 

Thread Priorities

The sections that follow describe the priorities of threads in the RTSS and Win32 environments.

RTSS Environment

The RTSS environment has no distinct priority classes, so the threads of all RTSS processes compete for the CPU using the thread priority only. An RTSS thread runs at one of 128 distinct priority levels.Threads execute in priority
order and in "first in, first out" order within any single priority(遇到牛B的让道,遇到同级的讲究先来后到)
. If a time quantum is set to 0, the thread will run to completion. If thetime
quantum is set to another value
, the thread will run for the specified time and then give up the CPU to another thread with the same priority(难道线程执行中会设定执行时间?). RTSS scheduling implements a priority inversion and deferred
priority demotion mechanism to eliminate unbounded priority inversion.

For example, RTSS mutex objects support a level-one priority promoting mechanism(这种leve-one不知道是一种什么机制). If a higher priority thread calls WFSO on a mutex object that is owned by a lower priority thread, the priority of
the mutex owner is promoted to the same priority as the higher priority thread. An attempt to demote the priority of a mutex owner thread will be deferred until the thread releases the mutex.

Win32 Environment

A Win32 program that links in RTX starts execution in the normal priority class, however, as soon as the program callsRtGetThreadPriority,RtSetThreadPriority,
or any other real-time priority function, the programs priority class becomes the real-time priority class

Table 1, RTSS to Win32 Thread Priority Mapping, shows how RTSS symbolic priority names translate to requests for aparticular Windows 2000 priority whenRtSetThreadPriority
is called by a Win32 program.

 

Table 1, RTSS to Win32 Thread Priority Mapping, shows how RTSS symbolic priority names translate to requests for aparticular Windows 2000 priority whenRtSetThreadPriority
is called by a Win32 program.

Table 1. RTSS to Win32 Thread Priority Mapping 

RTSS Symbolic Priority Name

RTSS Value

Windows 2000 Symbolic Priority Name for Real-Time Priority Class

Win32 Value

RT_PRIORITY_MIN

0

THREAD_PRIORITY_IDLE

16

RT_PRIORITY_MIN + 1

1

THREAD_PRIORITY_LOWEST

22

RT_PRIORITY_MIN + 2

2

THREAD_PRIORITY_BELOW_NORMAL

23

RT_PRIORITY_MIN + 3

3

THREAD_PRIORITY_NORMAL

24

RT_PRIORITY_MIN + 4

4

THREAD_PRIORITY_ABOVE_NORMAL

25

RT_PRIORITY_MIN + 5...+ 126

5...126

THREAD_PRIORITY_HIGHEST

26

RT_PRIORITY_MAX

127

THREAD_PRIORITY_TIME_CRITICAL

31

Table 1 shows, for example, that RtSetThreadPriority(Thread, RT_PRIORITY_MIN+1) will result in a call toSetThreadPriority(Thread,
THREAD_PRIORITY_LOWEST) by the Win32 version of the RTX interfaces.

Any value from RT_PRIORITY_MIN+5 to RT_PRIORITY_MIN+126 will set the thread at THREAD_PRIORITY_HIGHEST and RT_PRIORITY_MAX will result in THREAD_PRIORITY_TIME_CRITICAL priority. These mappings are fixed and designed to
preserve relative ordering among thread priorities.

If a Win32 program calls RtGetThreadPriority, the real-time priority specified in the call toRtSetThreadPriority returns. There are some restrictions,
however. The most likely source of confusion is when calls toRtSetThreadPriority andSetThreadPriority are mixed. The library may not always
understand the RTSS priority when a duplicated thread handle is used, and it will return RT_PRIORITY_MIN+5 instead of RT_PRIORITY_MIN+6 through RT_PRIORITY_MIN+126. Threads that set and get their own RTSS priorities (such as specifying the thread withGetCurrentThread),
will always get the RTSS priority that was set.

Win32 programs should use the Rt priority calls for the Win32 thread to claim other than the lowest RTSS scheduling priority when waiting on an RTSS synchronization object. For instance, a Win32 thread with an RTSS priority of RT_PRIORITY_MAX will own a
mutex before an RTSS thread waiting for the same mutex with a priority less than RT_PRIORITY_MAX.

Table 2, Win32 to RTSS Thread Priority Mapping, shows what callers of the Win32 "set" and "get" thread priority calls should expect in the RTSS environment. This table describes the inverse of the mapping shown in Table 1.

 

Table 2. Win32 to RTSS Thread Priority Mapping

 

Windows 2000 Symbolic Priority Name for Real-Time Priority Class

Value

RTSS Symbolic Priority Name

Value

THREAD_PRIORITY_IDLE

16

RT_PRIORITY_MIN

0

THREAD_PRIORITY_LOWEST

22

RT_PRIORITY_MIN + 1

1

THREAD_PRIORITY_BELOW_NORMAL

23

RT_PRIORITY_MIN + 2

2

THREAD_PRIORITY_NORMAL

24

RT_PRIORITY_MIN + 3

3

THREAD_PRIORITY_ABOVE_NORMAL

25

RT_PRIORITY_MIN + 4

4

THREAD_PRIORITY_HIGHEST

26

RT_PRIORITY_MIN + 5

5

THREAD_PRIORITY_TIME_CRITICAL

31

RT_PRIORITY_MAX

127

There are no additional priorities between THREAD_PRIORITY_IDLE and THREAD_PRIORITY_HIGHEST. If you need finer grain priorities, you should use the RTSS priority spectrum instead. Just as in Win32, this value specifies a thread priority that
is higher than all other priorities.

Win32 Environment Programming Considerations

A Win32 RTX linked program starts execution in the normal priority class, as soon as the program callsRtGetThreadPriority,RtSetThreadPriority,
or any other real-time priority function the programs priority class becomes the real-time priority class.

 

This is the desired behavior for most applications because it gives the process the best possible real-time performance. This does, however, cause problems when the Win32 threads have GUI components. When a thread in the REALTIME_PRIORITY_CLASS
interacts with the GUI side of Windows, slowdowns and lock-ups occur. You can avoid this problem when writing a Win32 application that has a GUI component (and links to rtapi_win32.lib), by making sure that your program first makes this call:

 

SetPriorityClass( GetCurrentProcess(), NORMAL_PRIORITY_CLASS)

 

Note: If you do set your application's priority as described above, the application's GUI may not refresh its data if it is not the topmost window.

 启动一个进程的方法:

PROCESS_INFORMATION piProcInfoGPS;
STARTUPINFO siStartupInfo;
SECURITY_ATTRIBUTES saProcess, saThread;

memset(&siStartupInfo, 0x00, sizeof(siStartupInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
siStartupInfo.wShowWindow = SW_HIDE;
siStartupInfo.dwFlags = STARTF_USESHOWWINDOW;

saProcess.nLength = sizeof(saProcess);
saProcess.lpSecurityDescriptor = NULL;
saProcess.bInheritHandle = TRUE;

saThread.nLength = sizeof(saThread);
saThread.lpSecurityDescriptor = NULL;
saThread.bInheritHandle = TRUE;

wsprintf(m_szMachineExeFile, _T("%ws\\%ws"), g_data.GetStartupPath(), UU_ACCE_PROCESS_NAME);

if(!CreateProcess(m_szMachineExeFile, NULL, &saProcess, &saThread, TRUE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &siStartupInfo, &piProcInfoGPS))
{
  Sleep(5);
  if(!CreateProcess(m_szMachineExeFile,   NULL, &saProcess, &saThread, TRUE,  CREATE_DEFAULT_ERROR_MODE, NULL,  NULL, &siStartupInfo, &piProcInfoGPS))
  {
    SYSTEM_LOG(_T("uuAccelerater.exe ha   s   broken,please repaire!error code:%lu"),  GetLastError());
    m_buuAcceleraterIsBroken=true;
    return false;
  }
}

m_hProcessPlus = piProcInfoGPS.hProcess; 

 

 

 

抱歉!评论已关闭.