有没有一种安全的方法来检查是否存在pthread?

时间:2014-10-24 00:16:33

标签: c multithreading pthreads

我正在测试一个有关详细错误处理的想法,并希望让一个线程能够调用“getlasterror”#39;在需要处理错误时起作用。我使用便宜且简单的结构指针指针,但也使用pthread_t id覆盖前一个条目(如果不需要或已处理错误信息)。

从stackoverflow帖子How do you query a pthread to see if it is still running?How do I determine if a pthread is alive?,似乎使用pthread_kill发送虚假信号可能不安全。是否真的没有替代机制来检查是否存在具有id的pthread?或者我可以禁用线程ID在运行时重用的能力吗? (我知道后者可能是安全问题......)

我之前没有写过任何代码,但是我在leafpad中粗略地掀起了我的计划下面的内容(所以忽略任何语法错误,如果有的话!)。兴趣点自然是动态清理,如果应用程序正在关闭则没有问题。任何其他替代想法也将受到欢迎:)

如果适用,这将是一个客户端/服务器程序,因此每个accept()都会存在一个新线程。

struct error_info_structs
{
    struct error_info** errs;   // error_info struct with details
    pthread_t**         tids;   // thread ids for each struct
    uint32_t            num;    // number of error_info structs and thread ids
    pthread_mutex_lock  lock;   // runtime locker
};
struct error_info_structs   g_errs;
// assume we've done necessary initialization...

struct error_info*
get_last_runtime_error()
{
    struct error_info*  retval = NULL;
    pthread_t           tid = pthread_self();

    pthread_mutex_lock(&g_errs.lock);

    for ( uint32_t i = 0; i < g_errs.num; i++ )
    {
        if ( pthread_equal(g_errs.tids[i], tid) )
        {
            retval = g_errs.errs[i];
            goto release_lock;
        }
    }

release_lock:
    pthread_mutex_unlock(&g_errs.lock);
    return retval;
}


void
raise_runtime_error(struct error_info* ei)
{
    pthread_t   tid = pthread_self();

    pthread_mutex_lock(&g_errs.lock);

    for ( uint32_t i = 0; i < g_errs.num; i++ )
    {
        if ( pthread_equal(g_errs.tids[i], tid) )
        {
            // replace existing
            memcpy(&g_errs.errs[i], ei, sizeof(error_info));
            goto release_lock;
        }

        /*
         * Dynamic cleanup to lower risk of resource exhaustion.
         * Do it here, where we actually allocate the memory, forcing
         * this to be processed at least whenever a new thread raises
         * an error.
         */
        if ( pthread_kill(g_errs.tids[i], 0) != 0 )
        {
            // doesn't exist, free memory. safe to adjust counter.
            free(g_errs.errs[i]);
            free(g_errs.tids[i]);
            g_errs.num--;
        }
    }

    /*
     * first error reported by this thread id. allocate memory to hold its
     * details, eventually free when thread no longer exists.
     */

    struct error_info*  newei = malloc(sizeof(struct error_info));
    if ( newei == NULL )
    {
        goto release_lock;
    }

    pthread_t*      newt = malloc(sizeof(pthread_t));
    if ( newt == NULL )
    {
        free(newei);
        goto release_lock;
    }

    // realloc-bits omitted

    g_errs.errs[g_errs.num] = newei;
    g_errs.tids[g_errs.num] = newt;
    g_errs.num++;

release_lock:
    pthread_mutex_unlock(&g_errs.lock);
}

1 个答案:

答案 0 :(得分:0)

  

...我可以禁用线程ID在运行时重用的功能吗?

不,你不能。