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>
2018
2019
2020
2021
2022
2023
2024
- 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>
2018
2019
2020
2021
2022
2023
2024
|