Date: Mon, 28 Dec 1998 17:31:12 -0500 From: Kelly Yancey <kbyanc@freedomnet.com> To: freebsd-hackers@FreeBSD.ORG Subject: pthreads question/problem... Message-ID: <368806B0.721938BF@freedomnet.com>
next in thread | raw e-mail | index | archive | help
I have a system running FreeBSD 2.2-980711-SNAP (2.2.7) and have been working on developing a small multithreaded test program (just to make sure I've got the semantics and whatnot right). The basic idea is that I start a small pool of "worker" threads that wait to service requests. In this little test program, requests are randomly generated by the main thread (ie. original thread of execution). To pass the request to a free worker thread, the main thread scans the pool of worker threads using pthread_mutex_trylock() until it finds one that has it's in-use mutex unlocked. As I understand, trylock is supposed to lock the mutex if it is unlocked. At which point, I fill in the data structures for that worker thread and call pthread_cond_signal() to unblock it. All of that works like a charm. The problem is that when the worker thread is done processing it calls pthread_mutex_unlock() on the in-use mutex to make the thread available to service a new request. However, the unlock call always returns EINVAL (invalid argument). Now, I'm not asking for anyone to debug my code...that's my own headache, but here is the thread pool definition (pardon the long comments): struct threadinfo { pthread_t threadid; /* thread ID of thread servicing this structure */ pthread_cond_t waitcondition; /* condition variable used while waiting for data */ pthread_mutex_t waitmutex; /* mutex used to protect data from simultanious access */ pthread_mutex_t inuse; /* mutex used to indicate the TCB is currently active */ long data; /* data given to thread to process */ }; struct threadinfo TCB[NUMTHREADS]; /* array of thread control blocks (TCBs)...each TCB is used to pass data to a single executi ng thread */ The point being that the mutexes are global data and each thread is passed a pointer to the structure that it is supposed to watch when the thread is started. (When I say "watch" I mean which structure's conditional variable it will block awaiting a signal). The main thread sets the mutex, the worker thread unlocks the mutex...or I should say tries to. What I end up seeing is that the mutex stays locked and I eventually run out of worker threads as they all remain "in-use". And before anyone asks...yes, I have verified that the parameter I mass to unlock is indeed the same as the one I passed to lock (by using printf() with %p to verify the pointer addresses). Is there something wrong with the pthreads implementation of mutexes as of this snap that may be fixed in 2.2.8 (I'm not quite ready to go to 3.0 yet)? Or am I missing some fundamental aspect of multithreaded programming? It seems to me that being able to manipulate mutexes from separate threads is a must for threads to be of any use. I greately appreciate any pointers anyone can give me...perhaps I can keep my sanity yet :) Kelly -- Kelly Yancey "Bill Gates is only a white Persian cat and ~kbyanc@freedomnet.com~ a monocle away from being the villain in a James Bond movie" - comedian Dennis Miller To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?368806B0.721938BF>