ACE example APG example

xiaoxiao2021-03-06  37

APG example of an Active_Objects example

MD, hard scalp, analyze this only 100 rows of procedures.

Issue list:

ACE_TRACE does not work: Didn't see the output of ACE_TRACE in debugging, after Google, it is found that the ACE_NTRACE is required to be 0 so that you can turn on TRACE tracking.

ACE Auto Pointer Problem: There is such code when watching the program: In the SCHEDULER class's SVC function, there is such code: Auto_Ptr Request (this-> Activation_queue_.dequeue ()); Well, this is A circular internal code, each time the block acquired from Activation_Queue_, is released when auto_ptr next time this REQEUST is released, or is released when the Request is finally destroyed. This is the use of auto_ptr. I am not particularly habits. Because it is not that intuitive, this use is indeed possible to avoid a lot of problems. The cost is some insufficient transparency.

What kind of thing is ACE_FUTURE? In order to be able to completely solve this doubt, I decided to take the ACE_FUTURE to see. ACE_FUTURE is a template designed for asynchronous returns. He allows a write, multiple readings. After in-depth analysis, ACE_FUTURE is a container for loading results. If the quotation is 0, then this result will be destroyed. This is a little bit, in particular, that is, we can define a bunch of Ace_Future things, these things can refer to each other, each finger once, then add a number of references. When destroying this ACE_FUTURE, if the number of references is not 0, then this object is actually not destroyed. And it is protected for writing. This way, it is easy to write very simple code. In order to clearly explain this, we use this example in this example:

In an example program, the main program defines an array of ACE_FUTURE Results [10] to save the work result of the working thread. In a general design, either use the 10 array elements into the working thread, or the 10 array elements are used to save the results within the working thread. However, what is the example do?

ACE_FUTURE Results [10];

For (int i = 0; i <10; i )

Results [i] = controller.status_update ();

Is this controller.status_update returns the result of the thread internal? Let's take a look at this status_update.

ACE_FUTURE status_update ()

{

ACE_FUTURE Result;

This-> Scheduler_.enqueue (New Statusupdate (this-> controller_, result);

Return Result;

}

In the mind, Solidon, Shit, this is not to show that the result is actually leaping the life cycle, that is, the result, the result, does not destroy with the termination of the function, and It will bring the caller (actually there are three places, one is the result, one is the result of Statusupdate, and one, the return of the result) When the result of these three places, the last time When a result destroyed, I found my own quantity to zero 0, so I destroy myself. This increases the life cycle of the result. However, this will also introduce a problem, that is, because of the return, recreate an ACE_FUTURE r = result; then this Result will be destroyed, and then the caller Results [j] = r will then destroy. Then destroy this temporary return variable R.

For the sake of clear identification, I made a function to determine:

ACE_FUTURE stupid (void)

{

ACE_FUTURE Result (5);

Return Result;

}

The caller is like this:

ACE_FUTURE RS;

RS = stupid ();

If so, then this result is really destroyed when the RS is destroyed when the RS is destroyed in the RS destroyed results (in the ACE_FUTURE Result (5)).

If you call Stupid () without RS = stupid (); then this result is destroyed immediately after STUPID ().

When is this program created a thread? In the HA_CONTROLLERAGENTPROXY class, Activate () is called in the constructor of the member function. The thread created here is called. And start working from the SVC function.

After these questions, the structure of this program is solved. This program is a multi-threaded task schedule that demonstrates ACE. Mainly demonstrated between the task cooperation between ACE_METHOD_REQUEST and ACE_TASK_BASE, and the demo delivered using ACE_FUTURE to return value. There is also an example of the use of Auto_PTR.

Program analysis

According to the traditional analysis method, we start analyzing this example from the ACE_TMAIN main function.

INT ACE_TMAIN (int, ACE_TCHAR * []) ​​{ha_controlleragentproxy controller; ACE_FUTURE Results [10];

For (int i = 0; i <10; i ) Results [i] = controller.status_update (); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Begin Sleep 5 Seconds / N")))))); ACE_OS :: Sleep (5) // DO Other Work. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Sleep End, And Begin Get Results / N))));

// Get Results ... for (int J = 0; j <10; j ) {int result; results [j] .get (result); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("New Status_Update% D / N") ,} // cause the status_updater threads to exit. controller.exit (); ACE_THREAD_MANAGER :: Instance () -> Wait (); returnograph

The first is to define a class for controlling, this class, there will be a task scheduler, which creates a thread. In this class, there is a class object for controlling, this class object is used to add a return value each time two seconds. However, when starting, the type object used by this control does not work, but waits until the working thread is called next. After the main program defines this variable, threads for the work have been created and the task objects on the work queue are started.

Next, 10 return values ​​are defined. And use a loop to set up 10 tasks (update tasks). At the same time as the update task is set, the working thread gets this task from the work queue (see the SVC function) and calls the Call method of this task object. Calling the CALL method is currently calling the Call method for the StatusUpdate class. The CALL method for executing StatusUpdate will execute the addition of the addition to the control class and set the return value of the corresponding task object.

At the same time, the main thread will sleep for 5 seconds, after the sleep is completed, the main thread will take the return value in turn, which is very fast (because the Sleep is 5 seconds, so there should be two have been executed, there is a return value) There will be two return values, and the return value in the future is to appear.

Finally, the SVC function exits by pressing an exit task behind the task queue. Then use ACE_THREAD_MANAGER to wait for all threads to end.

difficulty

The definition of the constructor in the STATUSUPDATE class:

StatusUpdate (ha_controlleragent & controller, ace_future & returnval): Controller_ (Controller), ReturnVal_ (ReturnVal)

And we see: The defined member variables Controller_ and ReturnVal_ are not all quoted definitions:

One is: Ha_ControlleRagent & Controller_; one is ace_future returnval_;

We have doubts, why is there a difference? Whether the parameter design must be a reference design?

For Controller, it is designed to be referenced. Otherwise, it is a pointer design, because different StatusUpdate objects require the same Controller control object, so you need to reference your design or pointer design, the same, this requires the definition of member variables Controller. Quote or pointers.

But notice the design of this parameter for the ACE_FUTURE . Since this object may be cross-acting domain, if you assign a value with reference, it will lead to a member variable to point to an already released object, so you can't use the reference assignment, you can only assign it directly, through the ACE_FUTURE template It is a reference to the object itself. So on the parameter, it can be or can also be referenced. Just assign a value not a reference assignment. Executive detail analysis

1. Execute HA_CONTROLLERAGENTPROXY Controller.

2. Execute ACE_FUTURE Results [10];

3. Extroller.status_update ();

The main thread creates a controller.scheduler object scheduler.schedule {activate ();} Creating a Controller.Controller_ object Initialize the counter (for return value) Creating 10 ACE_FUTURE For return value to perform the first controller.status_update Create a ACE_FUTURE Return Value Create a StatusUpdate object (using the return value of the original created and the Controller.Controller_ object) pressed into the work queue of the Schedule (this time found why the Scheduler class inherits a press queue method) Setting A return value = return value just created

Execute the second to 10th Controller.status_update

Wait for 5 seconds. . . . . . Sub-thread

The thread creates a queue that starts waiting for Activation_Queue_ (because the queue is empty, it will wait). . . . . . . Receive the StatusUpdate object inside the queue Perform statusupdate.call () Set the return value 1 of Controller_ wait for 2 seconds. . . The output return value receives the StatusUpdate object inside the queue Perform statusupdate.call () Set the return value of Controller_ 1 waiting for 2 seconds

The main thread continues to wait. . . . Waiting for a return result immediately returns the execution wait for the second return result immediately returns the execution waiting, the third return result is waiting. Returns the execution waiting for the fourth return result waiting. . . . . Return

Extroller.exit is pressed into the SCHEDULE's work queue. This Call method of this exit object is just simply returned to one -1

Performing Waiting Thread Manager This INSTANCE is ended. . The program ended the child thread waiting for 2 seconds. . Output return value Execute StatusUpdate.Call () Setting Return Value = The return value of Controller_ Set the return value of Controller_ 1 Wait 2 seconds. . . Output return value Execute StatusUpdate.Call () Setting Return Value = The return value of Controller_ Set the return value of Controller_ 1 Wait 2 seconds. . . Output return value. . . . . . Receive the launch object exitmethod, execute exitMethod.call returns -1, so returning from SVC. Thread termination

Key words: ACE_FUTURE, ACE_TASK_BASE, ACE_METHOD_REQUEST, AUTO_PTR

Not very habitual way of thinking. But it has gradually understood.

转载请注明原文地址:https://www.9cbs.com/read-71230.html

New Post(0)