Best way to share data between threads
Hi all, I'm porting some libraries from Win32 to BSD/Linux. In the original code, I receive a Windows event with an attached COM object. Under *nix, what is the best way to copy this? A message, followed by accessing shared memory between threads? jm -- ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: Best way to share data between threads
On 2005-02-22 05:50, Jonathon McKitrick <[EMAIL PROTECTED]> wrote: > > Hi all, > I'm porting some libraries from Win32 to BSD/Linux. In the original > code, I receive a Windows event with an attached COM object. > > Under *nix, what is the best way to copy this? A message, followed > by accessing shared memory between threads? Does the message really have to be shared across many threads? I'm only asking because thread-specific message queues are not that hard to build with pthreads. You will only need a per-thread queue to hold messages and a master thread that 'dispatches' messages to the proper thread/queue. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: Best way to share data between threads
On Tue, Feb 22, 2005 at 08:38:11AM +0200, Giorgos Keramidas wrote: : On 2005-02-22 05:50, Jonathon McKitrick <[EMAIL PROTECTED]> wrote: : > : > Hi all, : > I'm porting some libraries from Win32 to BSD/Linux. In the original : > code, I receive a Windows event with an attached COM object. : > : > Under *nix, what is the best way to copy this? A message, followed : > by accessing shared memory between threads? : : Does the message really have to be shared across many threads? I'm : only asking because thread-specific message queues are not that hard : to build with pthreads. You will only need a per-thread queue to hold : messages and a master thread that 'dispatches' messages to the proper : thread/queue. Well, there will be a data acquisition thread, that when finished, will need to signal the main processing thread that a new data object has arrived. Jonathon McKitrick -- My other computer is your Windows box. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: Best way to share data between threads
On 2005-02-22 12:19, Jonathon McKitrick <[EMAIL PROTECTED]> wrote: >On Tue, Feb 22, 2005 at 08:38:11AM +0200, Giorgos Keramidas wrote: >:On 2005-02-22 05:50, Jonathon McKitrick <[EMAIL PROTECTED]> wrote: >:> >:> Hi all, >:> I'm porting some libraries from Win32 to BSD/Linux. In the >:> original code, I receive a Windows event with an attached COM >:> object. >:> >:> Under *nix, what is the best way to copy this? A message, >:> followed by accessing shared memory between threads? >: >: Does the message really have to be shared across many threads? I'm >: only asking because thread-specific message queues are not that >: hard to build with pthreads. You will only need a per-thread queue >: to hold messages and a master thread that 'dispatches' messages to >: the proper thread/queue. > > Well, there will be a data acquisition thread, that when finished, > will need to signal the main processing thread that a new data > object has arrived. There are a couple of ways to do the notification: 1) Explicit notification using a condition variable. 2) No notification at all, but restructuring of the thread code to use message queues. The first can be accomplished by associating a pthread_cond_t with the data storage area and explicit signalling of the processing thread. Every time the processing thread has nothing to do (i.e. no data being processed at the time), it blocks on the condition variable and waits until the data acquisition thread awakes it. The second way to solve this is to use minimal synchronization (i.e. a mutex to protect a common message queue) and a queue of currently pending messages. The data acquisition thread gets a copy of the data and pushes it on the queue, leaving all further work to the processing thread. The processing threads awakes periodically, "polling" for new messages in the queue. When one is found, it is immediately processed. When no message is found, the processing thread sleeps for a small amount of time. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: Best way to share data between threads
On Tue, Feb 22, 2005 at 02:42:44PM +0200, Giorgos Keramidas wrote: : 1) Explicit notification using a condition variable. : : The first can be accomplished by associating a pthread_cond_t with the I think this is the approach I will use. As a matter of fact, I added it today for a different, more limited use, and it worked well. We have an instrument that needs firmware ftp'ed to it after a cold start, and I placed that into a pthread. I'll try the data acq thread soon. The only problem is that pthread_join doesn't seem to have a timeout feature. So if the thread hangs, I have no way of knowing. Jonathon McKitrick -- My other computer is your Windows box. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: Best way to share data between threads
On 2005-02-23 03:58, Jonathon McKitrick <[EMAIL PROTECTED]> wrote: >On Tue, Feb 22, 2005 at 02:42:44PM +0200, Giorgos Keramidas wrote: >: 1) Explicit notification using a condition variable. >: >: The first can be accomplished by associating a pthread_cond_t with the > > I think this is the approach I will use. As a matter of fact, I added it > today for a different, more limited use, and it worked well. We have an > instrument that needs firmware ftp'ed to it after a cold start, and I placed > that into a pthread. I'll try the data acq thread soon. > > The only problem is that pthread_join doesn't seem to have a timeout > feature. So if the thread hangs, I have no way of knowing. True. I usually get around this by polling on a thread flag until its state changes as expected or a timeout occurs. struct thread_data { pthread_mutex_t td_lock; pthread_t td_id; int td_flags; }; #define TDF_SPAWNING(1<<0) /* Thread is now spawning */ #define TDF_ACTIVE (1<<1) /* If set, thread is active */ #define TDF_CLOSE (1<<2) /* If set, thread closes*/ #define TDF_CLOSING (1<<3) /* Thread in close process */ The main thread that needs to know if a thread is active, keeps a list of thread_data structures around and passes pointers to these structures to pthread_create() as the thread 'arg'. Before calling pthread_create(), the main thread initializes a new thread_data structure and sets its TDF_SPAWNING flag. This way, even if the spawned thread takes a long time to start, the thread_data won't be ripped off from under its feet while it is still spawning. Then pthread_create() starts the new thread: struct thread_data *td; if (pthread_create(&(td->td_id), NULL, thread_main, td) != 0) die(); The pthread_main() function takes care of changing the state of the thread_data from TDF_SPAWNING to TDF_ACTIVE: void * thread_main(void *arg) { struct thread_data *td = (struct thread_data *)arg; if (td == NULL) return (NULL); if (pthread_mutex_lock(&(td->td_lock)) != 0) return (NULL); td->td_flags |= TDF_ACTIVE; td->td_flags &= ~(TDF_SPAWNING); if (pthread_mutex_unlock(&(td->td_lock)) != 0) panic(); Then the thread_main() function can go on doing other things, waiting for its TDF_CLOSE flag to be set. That is an indication that the thread should start cleaning up and stop running. As soon as the thread notices TDF_CLOSE is set, it locks thread_data, sets TDF_CLOSING and clears TDF_CLOSE. Then thread_data can be unlocked again, the thread can clean up, eventually ending up at the final part: if (pthread_mutex_lock(&(td->td_lock)) != 0) error(); td->td_flags &= ~(TDF_ACTIVE | TDF_CLOSING); if (pthread_mutex_unlock(&(td->td_lock)) != 0) error(); return (arg); Done. The fact that TDF_ACTIVE is no longer set, means that the thread has already exited, so its safe to call pthread_join() on its td->td_id and it won't block indefinitely. - Giorgos ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "[EMAIL PROTECTED]"