Reputation: 6758
OS is Linux, working with pthreads
I have two worker threads that run forever, until a stop variable takes value true, and the threads terminate gracefully. Instead of doing busy waiting both threads call pthread_cond_wait until a signal notifies for a new task. The system works well.
It is requested to create an "info" thread that will print some debugging information. The info thread will try to read and print information every 30 seconds.Part of this info, I would like to be the STATE of each worker thread. Is it possible to find if a thread is blocked in "pthread_cond_wait"? If the thread waits is pthread_cond_wait then STATE==waiting else the STATE==running.
while ( (sharedvaluffer == 0) && (doneflag == 0) ) {
pthread_cond_wait (&taks_added, &buffer);
}
Of course we can do that we more code. We can add to the above snippet a global variable that marks that thread as locked. The code can be done
while ( (sharedvaluffer == 0) && (doneflag == 0) ) {
lock;
i_am_waiting = truel
unlock
pthread_cond_wait (&taks_added, &buffer);
}
The question is, if there is an easier more scalable way. The stack of a waiting thread is
Thread 6 (Thread 0x40800940 (LWP 20732)):
#0 0x00002ba4567a9326 in pthread_cond_wait@@GLIBC_2.3.2 ()
#1 0x00000000007ce2ed in worker(void*) ()
#2 0x00002ba4567a5193 in start_thread () from /lib64/libpthread.so.0
#3 0x00002ba458a82f0d in clone () from /lib64/libc.so.6
Upvotes: 8
Views: 1264
Reputation: 32240
You could use the return of pthread_self()
as identifier for the mutex ownership. Store and compare. Since a mutex can be acquired by a single thread at once, you will know which thread is running (not waiting), and which are not.
Upvotes: 0
Reputation: 64068
I would go the simple route and just include a state enum per thread. Prior to each conceptual state change you would alter the state.
void worker(void* parm)
{
threadstate_t *state = (threadstate_t*)parm;
/* ... */
while (...) {
state->current = STATE_WORKING;
/* ... */
state->current = STATE_WAITING;
/* res = pthread_cond_wait(cond, mutex); */
}
}
Then in your interrogration thread:
void worker_dbg(void* parm)
{
threadstate_t *states = (threadstate_t*)parm;
int i;
while (run) {
for (i = 0; i < NWORKERS; ++i) {
/* _state is a map of states to strings */
printf("Thread %d: %s\n", states[i].id, _state[states[i].current]);
}
sleep(30);
}
}
If you're off by 30 seconds because the state got updated right after you printed, it doesn't really matter. No need to lock on the state as you only write from the owning worker and you only read from the debug thread.
Upvotes: 1
Reputation: 10490
You could register a shared structure s in the mutex with pthread_mutexattr_getpshared, where each thread registers its state (running, not running) with the aid of pthread_self()
.
Before checking the condition variable, you can set s[pthread_self()]->state = WAITING
, and after the check you can set s[pthread_self()]->state = WORKING
.
Be sure to design the structure such as no race condition will occur.
Upvotes: 1
Reputation: 33655
Presumably you are using a mutex which is locked when the condition is notified, if so, in your information thread, simply try locking that mutex - if you acquire it, well it's possible that at the time you sampled, the thread is waiting, else if it would block, then you know the thread is doing it's thing (i.e. it has acquired that mutex which means it's in it's critical section)
Upvotes: 0