ACE

xiaoxiao2021-03-06  47

ACE_FUTURE implements a single-write multi-read mode, which can be used to return the results of asynchronous method to return

Activate the object scheduler, inherited thread base type ACE_TASK_BASE

1) Method Requests SVR () 2) method Request to enter the Work () 3) method request to process Work_i ()

ACE_Method_call the call function function established Prime_Scheduler class method request process correlation function work_i. Particular function Call ACE_Method_call call transpose Prime_Scheduler function work_i (), work_i () returns the value returned to the set function, then the ACE_Future set function then To the SET function of the ACE_FUTURE_REP to generate the desired result value value_ and save the ACE_FUTRUE_REP. Then ACE_FUTRUE's function ready checks if there is a result value, it is also the value pointer generated by the ACE_FUTURE_REP to detect the value pointer to the set function, ACE_FURTURE The function get goes to get the result value.

A Call pure virtual function is included in the ACE_METHOD_REQUEST class

Class ACE_EXPORT ACE_METHOD_REQUEST

{

PUBLIC:

ACE_METHOD_REQUEST (unsigned long priority = 0);

Virtual ~ ACE_METHOD_REQUEST (VOID);

Unsigned long priority (void) const;

Void Priority (UNSIGNED Long Prio);

Virtual Int Call (void) = 0;

protected:

Unsigned long priority_;

}

Class prime_scheduler: public ace_task_base

{

PUBLIC:

// Initialization

Virtual int open (void * args = 0);

//termination

Virtual Int Close (u_long flags = 0);

/ / Activate some method of the proxy interface of the object

ACE_FUTURE WORK (u_long param, int count = 1);

ACE_FUTURE Name (Void);

Void End (Void);

protected:

// Run the event loop

Virtual Int SVC (Void);

// Top two methods Work, Name implementation

U_long Work_i (U_LONG, INT);

Const ace_tchar * name_i (void);

Private:

// Activate the object queue

ACE_ACTIVATION_QUEUE ACTIVATION_QUE_;

// Activate the object pointer

PRIME_SCHEDULER * SCHEDULER_;

}

1) Request the method to start processing the method in the active queue request call int prime_scheduler :: SVC (Void)

{

For (;;)

{

// List the next method call request (we use the smart pointer to ensure exception MO clear)

Auto_PTR MO (this-> Activation_queue_.dequeue ());

ACE_DEBUG ((lm_debug,

ACE_TEXT ("(% T) Calling Method Request / N")))))))))))

// call it

IF (Mo-> Call () == -1)

Break;

}

}

2) Requesting the need to enter the dispatch, requesting the work entered function Work, mainly to request the method to enter a column_future

Prime_scheduler :: Work (u_long newparam,

INT newcount) {

/ / Judgment the dispatcher pointer of the dispatcher's internal

IF (this-> scheduler_) {

Return this-> Scheduler_-> Work (newparam, newcount);

}

// No, use the activation object queue directly

Else {

ACE_FUTURE New_FUTURE;

// Method requests to enter.

this-> Activation_queue_.enqueue

(New Method_Request_Work (this,

NewParam,

Newcount,

New_future));

Return new_future;

}

}

3) Request processing // This is where Work happens. This method is called in the Call function in the method_request_work class.

U_long

Prime_scheduler :: Work_i (u_long param,

INT country

{

ACE_UNUSED_ARG (Count);

Return Ace :: IS_PRIME (param, 2, param / 2);

}

Method requests work class method_request_Work implementation, constructor is incorporated into activation object dispattors

Class method_request_work: public ace_method_request

{

Method_Request_Work (prime_scheduler *,

U_long,

Int,

ACE_FUTURE &);

Virtual Int Call (Void)

{

// Distribute the operation and save the result to FUTRUE, we note that the parameter 1 of the set is

// Scheduling Work_i function

Return this-> Future_Result_.Set (this-> scheduler _-> work_i

(this-> param_,

this-> count_)));

}

Pivate:

PRIME_SCHEDULER * SCHEDULER_;

U_long param_;

INT count_;

ACE_FUTURE FUTURE_RESULT_;

}

INT main () {prime_scheduler * andres, * peter, * Helmut, * matias

Create four activation objects.

For (int i = 0; i

{

{

ACE_FUTURE FRESULTA;

ACE_FUTURE FRESULTB;

ACE_FUTURE FRESULTC;

ACE_FUTURE FRESULTD;

ACE_FUTURE FRESULTE;

ACE_FUTURE fname;

/ / Method Requests to enter, wait for object activation calls, they are in the scheduling thread SVR to perform FRESULTA = Andres-> Work (9013);

FResultb = peter-> work (9013);

FResultc = Helmut-> Work (9013);

FResultd = Matias-> Work (9013);

// See if there is a result of IF (Fresulta.Ready ())

IF (i% 3 == 0)

{

// Cancel Futures ...

Fresulta.cancel (10UL);

FResultb.cancel (20 ul);

Fresultc.cancel (30 ul); Fresultd.cancel (40UL);

}

// Get the result U_long Resulta = 0, Resultb = 0, Resultc = 0, resultd = 0, ResulTe = 0;

Fresulta.get (Resulta);

Fresultb.get (resultb);

FResultc.get (Resultc);

FResultd.get (resultd);

Fresulte.get (resulte);

}

// Close the activation object

Andres-> end ();

Peter-> end ();

Helmut-> end ();

Matias-> End ();

DELETE ANDRES;

Delete peter;

DELETE HELMUT;

DELETE MATIAS;

}

// Implement but write multi-read mode, can be used to return the result of asynchronous method to return, and the ACE_FUTURE is overloaded = operator.

Template

Class ace_future

{

PUBLIC:

// Multiple constructor

ACE_FUTURE (VOID);

ACE_FUTURE (Const Ace_Future & R);

ACE_FUTURE (Const T & R);

~ ACE_FUTURE (VOID);

// Operator overload

Void Operator = (Const ACE_FUTURE & r);

INT Operator == (Const ACE_FUTURE & r) Const;

INT Operator! = (Const ACE_FUTURE & r) const;

Operator t ();

Int Cancel (Const T & R);

Int Cancel (Void);

Int set (Const T & R);

INT GET (T & Value, ACE_TIME_VALUE * TV = 0) const;

INT Ready (Void) Const;

Int Attach (ACE_FUTURE_OBSERVER * OBServer);

INT DETACH (ACE_FUTURE_OBSERVER * OBServer);

Void dump (void) const;

ACE_FUTURE_REP * GET_REP (VOID);

ACE_ALLOC_HOOK_DECLARE;

Private:

/// Do not allow new, delete, & operator

Void * Operator new (size_t nbytes);

Void Operator delete (void *);

Void Operator & ();

/// Protect .

Typedef ace_future_rep future_rep;

FUTURE_REP * FUTURE_REP_;

}

Template

Class ACE_FUTURE_OBSERVER

{

PUBLIC:

Virtual ~ ACE_FUTURE_OBSERVER (VOID);

Virtual Void Update (Const Ace_Future & Future) = 0;

ACE_ALLOC_HOOK_DECLARE;

protected:

ACE_FUTURE_OBSERVER (VOID);

}

Assign this-> future_rep_, and count template voidace_future :: operator = (consT ace_future & rhs)

{

ACE_FUTURE & R = (ACE_FUTURE &) RHS;

FUTURE_REP :: Assign (this-> future_rep_,

FUTURE_REP :: attach (r.future_rep_);

}

The attach function is referenced template ace_future_rep *

ACE_FUTURE_REP :: attach (ACE_FUTURE_REP * & rep)

{

ACE_ASSERT (Rep! = 0);

// use value_ready_mutex_ for Both Condition and Ref Count Management

ACE_MT (ACE_GUARD R_MON (rep-> value_ready_mutex_);

rep-> Ref_count_;

RETURN REP;

}

Assign ACE_FURTURE member ace_furture_rep template void

ACE_FUTURE_REP :: Assign (ACE_FUTURE_REP * & rep, ACE_FUTURE_REP * new_rep)

{

ACE_ASSERT (Rep! = 0);

ACE_ASSERT (new_rep! = 0);

// use value_ready_mutex_ for Both Condition and Ref Count Management

ACE_MT (ACE_THREAD_MUTEX, R_MON, REP-> Value_Ready_Mutex_);

ACE_FUTURE_REP * OLD = REP;

Rep = new_rep;

// Detached Old Last for Exception Safety

IF (il-> ref_count _-- == 0)

{

ACE_MT (R_Mon.Release ());

// We do not need the lock when deleding the representation.

// there shouth be no side effects from deletring rep and we don

// Not Want To Release A deleted Mutex.

DELETE OLD;

}

}

ACE_FUTURE Function SET Indirect Call Member's ACE_FUTURE_REP SET Function Template int

ACE_FUTURE :: Set (Const T & R)

{

/ / Give the result pointer to the ACE_FUTURE_REP.

Return this-> Future_rep_-> set (r, * this);

}

Template INT

ACE_FUTURE_REP :: Set (Const T & R,

ACE_FUTURE & Caller)

{

// If the value has been generated, it is ignored.

IF (this-> value_ == 0) {

ACE_MT (ACE_GUARD_RETURN (ACE_THREAD_MUTEX,

ACE_MON,

this-> value_ready_mutex_,

-1));

/ / Not, then a result value, note that use dual check lock mode to avoid multiple assignments

IF (this-> value_ == 0) // has no value, resulting

{

ACE_NEW_RETURN (this-> Value_,

T (r),

-1);

// Remove and Notify All Subscribed Observers.

ACE_TYPENAME OBSERVER_COLLECTION :: Iterator =

This-> Observer_collection_.begin ();

ACE_TYPENAME OBSERVER_COLLECTION :: Iterator End =

this-> Observer_collection_.end ();

While (Iterator! = End)

{

Observer * Observer = * Iterator ;

Observer-> Update (Caller);

}

// For thread broadcast signals waiting for

Return this-> value_ready_.broadcast ();

}

}

Return 0;

}

Check result value

Template INT

ACE_FUTURE :: Ready (void) Const

{

// We'RE Ready if the ace_future_rep is ready ...

Return this-> FUTURE_REP_-> Ready ();

}

Simply determined whether the value pointer does not return to Template INT

ACE_FUTURE_REP :: Ready (void) Const

{

Return this-> Value_! = 0;

}

Get the result value, update So ACE_FUTURE_OBSERVER TEMPLATE int

ACE_FUTURE_REP :: Get (T & Value,

ACE_TIME_VALUE * TV) Const

{

// if the value is already product, return it.

IF (this-> value_ == 0)

{

ACE_MT (ACE_GUARD_RETURN (ACE_THREAD_MUTEX, ACE_MON,

ACE_CONST_CAST (ACE_THREAD_MUTEX &, THIS-> Value_ready_mutex_),

-1));

// if the value is not yet defined we must block unsteil the

// Producer Writes to it.

While (this-> value_ == 0)

// Perform a Timed Wait.

IF ((ACE_CONST_CAST (ACE_CONDITION_THREAD_MUTEX &, THIS-> Value_Ready_)). Wait (TV) == -1)

Return -1;

// deStructor Releases The Lock.

}

Value = * this-> value_;

Return 0;

}

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

New Post(0)