简体   繁体   中英

pthreads, how do I know that another thread inside the process is not waiting?

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

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.

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.

大概您正在使用一个互斥锁,当条件通知时,该互斥锁会被锁定;如果是这样,则在您的信息线程中,只需尝试锁定该互斥锁-如果您获取了该互斥锁,那么很可能在采样时线程正在等待,否则如果它阻塞了,那么您就知道线程正在执行此操作(即它已经获取了该互斥锁,这意味着它位于关键部分)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM