Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017 Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
<== Date ==> <== Thread ==>

Subject: Re: C++ multi threaded application.
From: Michael Davidsaver <mdavidsaver@gmail.com>
To: "Giacomo S." <giacomo.strangolino@elettra.eu>, Andrew Johnson <anj@aps.anl.gov>, tech-talk@aps.anl.gov
Cc: Lucio Zambon <lucio.zambon@elettra.eu>
Date: Mon, 4 Sep 2017 11:14:59 -0500
On 09/04/2017 04:08 AM, Giacomo S. wrote:
> On 09/01/2017 06:31 PM, Andrew Johnson wrote:
>...
>>> - the background thread implements a wait condition so that it sleeps
>>> until a new event arrives (for example, exit event or new variable to be
>>> monitored is added)
>> You should be aware that the Channel Access client library creates a
>> background thread for each separate IOC it connects to, and it calls
>> your callback routines from those threads. You have no control over
>> that, if you talk to PVs on 2 IOCs you will get callbacks from 2
>> threads. 
> 
> That's a relevant information. Thus, monitoring 100 PVs means at least
> 100 threads in the application.

Only if each PV is served by a separate IOC.  If all 100 are served by
one IOC, then there is only 1 socket and 2 threads to service it.

...
> Inside the connection_handler() i call
> ca_create_subscription()
> 
> 
> // Code is taken from camonitor's.
> //
> void CuMonitorActivity::connection_handler(connection_handler_args args)
> {
> 
...
>             /* ---------------- */
>             /* install monitor once with first connect */
>             ppv->status = ca_create_subscription(ppv->dbrType,
>                                                  ppv->reqElems,
>                                                  ppv->ch_id,
>                                                  eventMask,
>                                                 
> CuMonitorActivity::event_handler_cb,
>                                                  (void*)ppv,
>                                                  NULL);
>         }
>     }
>     else if ( args.op == CA_OP_CONN_DOWN ) {
>         nConn--;
>         ppv->status = ECA_DISCONN;
>         print_time_val_sts(ppv, reqElems);

Subscriptions are not automatically cleaned up on disconnect.  You'll
want to make sure you call ca_clear_subscription() here, and on exit, to
avoid the situation Andrew mentions.

You'll also want to look at ca_clear_channel() which must be paired with
ca_create_channel().


>     }
> }
> 
> 
>>
>>> From within connection_handler_cb I extract the current
>>> CuMonitorActivity instance (stored in pv's monitor_activity field) and I
>>> invoke the object's extraction method. Data is posted in the main thread.
>>>
>>> NOTE: I notice that connection_handler_cb is invoked from ANOTHER
>>> thread, not my main thread, not my secondary thread. This should be as
>>> expected I guess for things to work and given the ca_
>>> enable_preemptive_callback option.
>> Right, see my remarks about threading above. Note that you are allowed
>> to make calls to other CA routines from within your callbacks, and in
>> fact that is the recommended way to set up your subscriptions. However
>> you should be careful to only subscribe for data from a PV only once; if
>> the IOC gets restarted your connection handler will be called again on
>> reconnect, and unless you're careful that code might create a second
>> subscription to the same PV, which will result in your event callback
>> being run twice or more for each data update from the IOC.
>>
>>> * when I post an "exitEvent" on my secondary thread from the main one
>>> (e.g. the GUI is closed),  "ca_context_destroy();" is invoked in my
>>> secondary thread (not the Epics thread that calls connection_handler_cb
>>> during monitoring - is this OK? )
>> Yes, as long as the thread was attached to the CA context. You should
>> attach all threads that you want to make CA calls from to your original
>> context using ca_current_context() and ca_attach_context().
>>
>>> * Is there a way to ADD more PVs to monitor WHILE others are being
>>> monitored (for example, is it legit to call create_pvs() again ) ?
>> Yes, although you didn't show us your create_pvs() routine. You can add
>> and remove channels and subscriptions whenever you like; about the only
>> thing you can't call from within a callback routine is ca_pend_event().
> 
> OK, now it should be clear how I create the pvs.

A client does not create PVs.  From the prospective of a CA client a
"PV" is the address string provided when creating a Channel (analogous
to a URL).

> Could you tell me how to add and remove channels and subscriptions?

You are already doing this by calling ca_create_channel() and
ca_create_subscription().  Removal is ca_clear_channel() and
ca_clear_subscription().



> As to threading, all channel/monitor setup is made up in a secondary thread.
> The idea is thus to add and remove channels within that very secondary
> thread.
> So, as you stated, the callbacks would be invoked from the N different
> threads on the event callback within the
> CuMonitorActivity object.
> Data, from within the event callback, is then queued and posted on the
> main thread.
> I have now to check whether I need to lock guard the code within the
> event callback or not.
> 
> Nonetheless, if my observations are correct, that makes a good starting
> point.
> 
> Thanks for Your help.
> 
> Giacomo, Elettra, Trieste, Italy
> 
> 
>>
>>> * Are there any observations/corrections to my approach and to my
>>> statements above?
>> Go check out epicsQt before you spend more time reinventing the wheel.
>> There is a separate mailing list for EPICS users programming with Qt and
>> you might want to subscribe to that:
>>     http://www.aps.anl.gov/epics/qti-talk/index.php
>>
>> - Andrew
>>
> 


References:
C++ multi threaded application. Giacomo S.
Re: C++ multi threaded application. Andrew Johnson
Re: C++ multi threaded application. Giacomo S.

Navigate by Date:
Prev: Re: Archiver: Problems with disconnected PVs Gabriel de Souza Fedel
Next: data refresh and add pv 梁雅翔
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
Navigate by Thread:
Prev: Re: C++ multi threaded application. Giacomo S.
Next: Re: C++ multi threaded application. Giacomo S.
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
ANJ, 05 Sep 2017 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·