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 2025 | 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 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | RE: Multithreading in R3.14.9 - preemptive callbacks not working. |
From: | "Douglas Morrison" <[email protected]> |
To: | "Jeff Hill" <[email protected]>, <[email protected]> |
Date: | Wed, 21 Jan 2009 09:02:55 -1000 |
That did it. Thank you! Douglas A. T. Morrison Software Engineer C.A.R.A - W. M. Keck Observatory Office: (808)881-3539 Cell: (808)937-0998 From: Jeff Hill
[mailto:[email protected]] Hello Doug, I suspect that it
will work as you were expecting in the first program if you add a ca_flush call
after the ca_add_event call. Let me know if that doesn’t take care of it
and I will have a closer look. Jeff Hill From: [email protected]
[mailto:[email protected]] On
Behalf Of Douglas Morrison Hello, I am running EPICS R3.14.9 on a Solaris 10 machine, and am
having difficulties implementing a multithreaded event monitoring application.
The goal is for the main thread to open channel connections, and wait for user
commands to perform other tasks. An auxiliary thread would be responsible for
processing channel events as they occur. I have read in the 3.14 users manual that when the context
is created using ca_enable_preemptive_callback, the CA library will spawn
auxiliary threads that will automatically execute event callbacks. I use the
following code to open a channel and set a callback (error handling removed for
brevity): void connect_handler(struct connection_handler_args
connect_args) {
// Handle connection
events. } void event_handler(struct event_handler_args event_args) {
// Print data. } int main(…) { chid chId; int stat; stat =
ca_context_create(ca_enable_preemptive_callback); stat= ca_create_channel(argv[1],
connect_handler, argv[1], 49, &chId); // Give the connect request time to
process ca_pend_event(0.05); stat=ca_add_event(DBR_DOUBLE, chId,
event_handler, NULL, NULL); sleep(10.0); } Based on what I’ve read, I would expect that while the
main thread is sleeping, the CA auxiliary threads would be finding events and
executing the callback, however it never does (the actual database value is
update at 2 Hz). Is my understanding or setup of the CA connections incorrect
for this usage? As a fix, I acquire the ca_context right after I create it,
and attach an application thread to the context which is responsible for
executing periodic polling (again, error checking removed for brevity): struct ca_client_context* caContext = NULL; void* dispatcher(void* ctx) { stat = ca_attach_context(caContext); while(1) { ca_pend_event(0.0001); sleep(0.5); } return NULL; } int main(…) { … stat =
ca_context_create(ca_enable_preemptive_callback); caContext =
ca_current_context(); … pthread_create(&dispatchThread, NULL,
dispatcher, NULL); sleep(10.0); } Using this setup I successfully get callback events. Did I
misunderstand the documentation when it said the CA Library would create its
own event processing threads, and that the second method I emply is actually
the correct method? Final question: When using preemptive callbacks, performing
a select on the file descriptors created by channel connections no longer see
any change on the sockets. Why is this (what is the motivation)? Any help would be greatly appreciated. Douglas A. T. Morrison Software Engineer C.A.R.A - W. M. Keck Observatory Office: (808)881-3539 Cell: (808)937-0998 |