C:在执行任何操作之前打印出多个线程的 ID?

C: Printing out multiple threads' ID's before they execute anything?

我想根据用户希望创建的线程数生成多个线程,并且这些线程中的每一个都执行一个函数“readFiles”。但是,在每个线程都可以执行 readFiles 中的任何有意义的代码(由“...”表示)之前,我希望所有线程都在一种介绍性通知消息中打印出它们的线程 ID,所以像...

"Thread ID _____ is processing!"
"Thread ID _____ is processing!"
"Thread ID _____ is processing!"
    ...
    ...
    ...

...但显然使用我的代码,每个线程一次只有 运行ning 个,因此线程 ID 仅在每个新线程开始执行有意义的代码时打印出来,所以这个。 ..

"Thread ID _____ is processing!"
    ...
"Thread ID _____ is processing!"
    ...
"Thread ID _____ is processing!"
    ...

在我对每个特定的新线程调用 pthread_create() 之前,有没有办法获取线程 ID?或者有没有一种方法可以使这些线程(应该 运行 同时),推迟或暂停它们在 readFiles (它们的“...”)中执行有意义的代码,直到它们有每个都先打印出线程 ID 消息?非常感谢大家!!!这是我的代码,可以让您更好地了解我目前拥有的东西...

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

uint64_t gettid()
{
    pthread_t actual_tid = pthread_self();
    uint64_t threadId = 0;
    memcpy( &threadId, &actual_tid, sizeof( actual_tid ) );
    return threadId;
}


void *readFiles( void *args )
{
    pthread_mutex_lock(&mutex);


    uint64_t current_id = gettid();
    printf("Thread id = ");
    printf("%" PRIu64 , current_id );

    ...
    ...
    ...

    pthread_mutex_unlock(&mutex);
}


void alphabetcountmulthreads(int num_threads)
{

    pthread_t ids[num_threads];

    for ( int t = 0; t < num_threads; t++ )
    {
        
        if ( pthread_create( &ids[t], NULL, &readFiles, NULL ) != 0 )
        {
            fprintf( stderr, "error: Cannot create thread # %d\n", t );
            break;
        }
    }

    for ( int u = 0; u < num_threads; ++u )
    {
        if ( pthread_join( ids[u], NULL ) != 0 )
        {
            fprintf( stderr, "error: Cannot join thread # %d\N", u );
        }
    }    

}

您可以通过多种方式完成此操作。您可以使用信号——让每个线程向某种监视器线程发送信号,然后等待被告知 运行。一旦监控线程收到所有信号,它就会通知等待线程继续。您还可以使用条件变量或互斥锁实现类似的解决方案来锁定线程,直到所有线程都打印出它们的 ID。

实现线程池的一种简单方法是,在所有线程开始实际工作之前,每个线程都有机会进行准备工作,即具有额外的启动互斥体、关联的条件变量和就绪线程的计数器:

static pthread_mutex_t  prep_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t   prep_cond = PTHREAD_COND_INITIALIZER;
static volatile size_t  prep_count = 0;

static pthread_mutex_t  thread_mutex = PTHREAD_MUTEX_INITIALIZER;
static volatile size_t  thread_count = 0;

static inline pid_t gettid(void) { return syscall(SYS_gettid); }

static void *thread_function(void *idref)
{
    /* Get the number/index of this thread. */
    const size_t  num = *(pid_t *)idref;
    const pid_t   tid = gettid();

    /* Replace it with the Linux tid. */
    *(pid_t *)idref = tid;

    /* Block here until preparatory work can be done. */
    pthread_mutex_lock(&prep_mutex);

    printf("Thread %zu of %zu has started.\n", id + 1, thread_count);
    fflush(stdout);

    prep_count++;
    pthread_cond_signal(&prep_cond);
    pthread_mutex_unlock(&prep_mutex);

    /* Block until actual work can start. */
    pthread_mutex_lock(&thread_mutex);
    ...

创建线程池时,创建者持有两个互斥量。当它准备好让线程开始准备工作时,它释放 prep_mutex,等待 prep_cond 直到足够数量的线程完成准备工作(prep_count 足够高)。然后,它释放 thread_mutex.

int start_threads(size_t max_count)
{
    pthread_t       thread_id[max_count];
    pid_t           linux_tid[max_count];
    pthread_attr_t  attrs;
    int             err = 0;

    /* Assume no threads currently running */
    prep_count = thread_count = 0;

    /* Shrink stack size; the default is too large. */
    pthread_attr_init(&attrs);
    pthread_attr_setstacksize(&attrs, 2*PTHREAD_STACK_MIN);

    /* Grab the mutexes, so the threads will block initially. */
    pthread_mutex_lock(&prep_mutex);
    pthread_mutex_lock(&thread_mutex);

    while (thread_count < max_count) {
        linux_tid[thread_count] = thread_count;
        err = pthread_create(thread_id + thread_count, &attrs,
                             thread_function, linux_tid + thread_count);
        if (err)
            break;

        thread_count++;
    }

    /* Attributes are no longer needed. */
    pthread_attr_destroy(&attrs);

    /* No threads created at all? */
    if (thread_count < 1) {
        pthread_mutex_unlock(&prep_mutex);
        pthread_mutex_unlock(&thread_mutex);
        /* Return failure. */
        return err;
    }

    /* All threads have now been created; let them do prep work. */
    while (prep_count < thread_count) {
        pthread_cond_wait(&prep_cond, &prep_mutex);
    }
    pthread_mutex_unlock(&prep_mutex);

    /* All threads have finished their prep work; start working. */
    pthread_mutex_unlock(&thread_mutex);

    ...

上面最多创建 max_num 个线程,它们的 pthread ID 在 thread_id[] 中,它们的 Linux 个线程在 linux_tid[].

当线程启动时,它会获得一个指向存储 Linux tid 的位置的指针。最初,它包含线程的索引(“线程号”,从 0 开始),因此 thread_function 将其抓取为 num,获得 Linux tid 作为 tid,并将其存储到作为参数给定的位置。这样,原始线程和创建的线程都知道索引(num)、pthread ID(thread_id[]pthread_self())和Linux tid(linux_tid[]tid).

注意数组在 pthread_create() 调用中是如何取消引用的。如果 array 是一个数组,并且 index 是它的索引,那么 &(array[index]) == array + index.

上面,start_threads()函数不假设它可以启动所有max_num个线程。如果无法创建任何线程,它会使用非零 errno 数字执行 return,但如果它可以创建至少一个线程,一旦线程可以获取 prep_mutexthread_count将反映他们帮派中正确的线程数。 (没有理由仅仅因为您只能创建 53 个工作线程而不是 54 个而失败。)