I l @ ve RuBoard |
MotivationAll threads spawned by the Thread_Per_Connection _Logging_Server class run at the same priority, which by default is the value of the predefined macro ACE_DEFAULT_THREAD_PRIORITY. Certain types of networked applications, particularly those with real-time requirements, need more control over their thread priorities. It's possible to specify the priority of a newly create thread in ACE by passing a parameter to the ACE_Thread_ Manager::spawn () or spawn_n () methods . There are two problems with this approach, however:
Addressing these problems in each application is tedious and error prone, which is why ACE provides the ACE_Sched_Params wrapper facade class and the ACE_OS::sched_params () wrapper method. Class CapabilitiesThe ACE_Sched_Params class uses the Wrapper Facade pattern to guide the encapsulation of the OS scheduling class APIs discussed in Section 5.5. This class can be used with the ACE_OS::sched_params () method to provide the following capabilities:
The ACE_OS::sched_params () method encapsulates the OS-specific function(s) that manipulate the scheduling class and ACE_Sched_Params provides the values used by this method. The interface of the ACE_Sched_Params class is shown in Figure 9.3 and its key methods outlined in the following table:
Figure 9.3. The ACE_Sched_Params Class Diagram
The ACE_OS:: Sched_params () method is usually called from main () before any threads have been spawned. Since spawned threads inherit their parent's scheduling class and priority, this call sets the default base priority. Individual thread priorities can be designated when created by the ACE_Thread_Manager ::spawn () method or adjusted via ACE_OS ::thr_ prio() . ExampleTo show how ACE can be used to program OS real-time scheduling class features portably, we'll modify our thread-per-connection logging server example from Section 9.2. After a careful empirical analysis of our networked logging service deployments, we decided to give preference to connected clients , rather than to new connection requests . The thread that accepts connections will therefore run at a lower real-time priority than the threads we'll spawn to receive and process log records. In the RT_Thread_Per_Connection_Logging_Server.h file, we inherit from the Thread_Per_Connection_Logging_Server class to create a networked logging server whose threads will run in the real-time OS scheduling class. class RT_Thread_Per_Connection_Logging_Server : public Thread Per_Connection_Logging_Server { public: We next override the open () hook method to enable FIFO scheduling for all threads spawned in the process. By default, spawned threads will run at the minimum real-time thread priority. If the application lacks sufficient permissions, we fall back to running in the time-shared scheduling class. virtual int open (u_short port) { ACE_Sched_Params fifo_sched_params (ACE_SCHED_FIFO, ACE_Sched_Params::priority_min (ACE_SCHED_FIFO), ACE_SCOPE_PROCESS); if (ACE_OS::sched_params (fifo_sched_params) == -1) { if (errno == EPERM 11 errno == ENOTSUP) ACE_DEBUG ((LM_DEBUG, "Warning: user's not superuser, so " "we'll run in the time-shared class\n")); else ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_OS::sched_params ()") , -1); } // Initialize the parent classes. return Thread_Per_Connection Logging_Server::open (port); } Finally, we override the handle_data () method so that it increases the priority of each thread that processes log records from connected clients. virtual int handle_data (ACE_SOCK_Stream *logging_client) { int prio = ACE_Sched_Params::next_priority (ACE_SCHED_FIFO, ACE_Sched_Params::priority_min (ACE_SCHED_FIFO), ACE_SCOPE_THREAD); ACE_OS::thr_setprio (prio); return Thread_Per_Connection_Logging_Server::handle_data (logging client); } Our use of object-oriented design, C++ features, and ACE wrapper facades allows us to add real-time scheduling class behavior to our thread-per-connection logging server without changing any existing classes or writing any platform-specific code. The main () function is like the one from Section 9.2, with an instance of our RT_Thread_Per_Connection_Logging_Server class in place of Thread_Per_Connection_Logging_Server . |
I l @ ve RuBoard |