在持有互斥锁时调用pthread_create是否安全?

时间:2017-05-23 13:37:42

标签: multithreading pthreads mutex shared-state

假设我在访问某些共享状态时拥有持有互斥锁的代码。在某些时候,我确定我需要创建一个新线程,因此调用pthread_create,同时仍然持有互斥锁。这被认为是安全的吗?

假设我的共享状态是一个全局计数器,用于跟踪成功创建的pthread的数量,另一个线程使用此计数器在屏幕上显示实时信息。另外,我不希望pthreads的数量变得大于某个最大值(例如,确定性为10)。

让我们说计数器当前为9.如果我在调用pthread_create之前递增计数器然后释放互斥锁,则pthread_create可能会失败,然后计数器错误地显示更多线程(10 )比我实际成功创造(9)。

另一方面,如果我首先释放互斥锁,然后调用pthread_create,然后重新获取互斥锁以在调用成功时增加计数器,然后在释放互斥锁并从pthread_create返回之间,另一个线程可能有也称为pthread_create并递增计数器(至10)。因此,我将创建第11个pthread,计数器变为11.但我应该创建的pthreads不超过10个。

因此,似乎保证共享状态一致性的唯一方法是在调用pthread_create时保持互斥锁。但是我知道,一般来说,不应该在持有互斥锁时调用未知代码,所以我不知道在这种情况下可以做些什么。

编辑:以下是一些会出现此问题的示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void *do_stuff(void *arg);

int pthreads_counter = 0;
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

#define MAX_PTHREADS_COUNT 10

/* Could potentially be called from multiple threads simultaneously */
int create_thread_and_increment_counter()
{
    pthread_t thread;

    if (pthread_mutex_lock(&mtx) != 0)
        return -1;

    if (pthreads_counter >= MAX_PTHREADS_COUNT) {
        pthread_mutex_unlock(&mtx);
        return -1;
    }

    ++pthreads_counter;

    if (pthread_create(&thread, NULL, do_stuff, NULL) != 0) {
        --pthreads_counter;
        pthread_mutex_unlock(&mtx);
        return -1;
    }

    pthread_mutex_unlock(&mtx);
    return 0;
}

void *do_stuff(void *arg)
{
    /* do stuff */
    return NULL;
}

/* Created somewhere else */
void *display_thread(void *arg)
{
    while (1) {
        if (pthread_mutex_lock(&mtx) != 0)
            break;

        printf("%d\n", pthreads_counter);
        pthread_mutex_unlock(&mtx);
        usleep(1000000);
    }

    return NULL;
}

1 个答案:

答案 0 :(得分:1)

在持有互斥锁时调用pthread_create()可以。