c - C 中的 pthreads - pthread_exit

标签 c pthreads

出于某种原因,我认为在 main 函数末尾调用 pthread_exit(NULL) 将保证所有正在运行的线程(至少在 main 函数中创建)将在 之前完成运行main 可以退出。但是,当我在下面运行这段代码而不显式调用两个 pthread_join 函数(在 main 的末尾)时,我得到了一个段错误,这似乎是因为 main 函数在两个线程完成它们的工作之前已经退出,因此 char buffer 不再可用。但是,当我在 main 的末尾包含这两个 pthread_join 函数调用时,它会按预期运行。为了保证 main 不会在所有正在运行的线程完成之前退出,是否有必要为所有直接在 main 中初始化的线程显式调用 pthread_join

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
#include <semaphore.h>
#define NUM_CHAR 1024
#define BUFFER_SIZE 8

typedef struct {
    pthread_mutex_t mutex; 
    sem_t full;
    sem_t empty;
    char* buffer;
} Context;

void *Reader(void* arg) {
    Context* context = (Context*) arg;
    for (int i = 0; i < NUM_CHAR; ++i) {
        sem_wait(&context->full);
        pthread_mutex_lock(&(context->mutex));
        char c = context->buffer[i % BUFFER_SIZE];
        pthread_mutex_unlock(&(context->mutex));
        sem_post(&context->empty);

        printf("%c", c);
    }
    printf("\n");
    return NULL;
}

void *Writer(void* arg) {
    Context* context = (Context*) arg;
    for (int i = 0; i < NUM_CHAR; ++i) {
        sem_wait(&context->empty);
        pthread_mutex_lock(&(context->mutex));
        context->buffer[i % BUFFER_SIZE] = 'a' + (rand() % 26);
        float ranFloat = (float) rand() / RAND_MAX;
        if (ranFloat < 0.5) sleep(0.2);
        pthread_mutex_unlock(&(context->mutex));
        sem_post(&context->full);
    }
    return NULL;
}

int main() {
    char buffer[BUFFER_SIZE];
    pthread_t reader, writer;
    Context context;
    srand(time(NULL));
    int status = 0;
    status = pthread_mutex_init(&context.mutex, NULL);
    status = sem_init(&context.full,0,0);
    status = sem_init(&context.empty,0, BUFFER_SIZE);
    context.buffer = buffer;

    status = pthread_create(&reader, NULL, Reader, &context);
    status = pthread_create(&writer, NULL, Writer, &context);

    pthread_join(reader,NULL);   // This line seems to be necessary
    pthread_join(writer,NULL);   // This line seems to be necessary

    pthread_exit(NULL);
    return 0;
}

如果是这种情况,我该如何处理使用相同线程标识符创建大量相同线程(如以下代码)的情况?在那种情况下,我如何确保所有线程都在 main 退出之前完成?我真的必须保留一组 NUM_STUDENTS pthread_t 标识符才能执行此操作吗?我想我可以通过让学生线程发出信号量然后让 main 函数在该信号量上等待来做到这一点,但是真的没有更简单的方法吗?

int main()
{
    pthread_t thread;
    for (int i = 0; i < NUM_STUDENTS; i++)
        pthread_create(&thread,NULL,Student,NULL);  // Threads 
    // Make sure that all student threads have finished
    exit(0);
}

最佳答案

pthread_exit() 是线程调用来终止自身执行的函数。对于您给出的情况,不能从您的主程序线程中调用它。

如您所知,pthread_join() 是等待来自 main() 的可连接线程完成的正确方法。

此外,您已经发现,您需要维护从 pthread_create() 返回的值以传递给 pthread_join()

这意味着如果您打算使用 pthread_join(),则不能对您创建的所有线程使用相同的 pthread_t 变量。

相反,构建一个 pthread_t 数组,以便您拥有每个线程 ID 的副本。

关于c - C 中的 pthreads - pthread_exit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3330048/

相关文章:

c - 板载 LED,无法打开/关闭

c - 如何在二进制 *.dat 文件中存储或打印信息? C编程

c - POSIX - 信号量、互斥体、线程 C

PHP pthreads : Thread dosen't executes methods from other objects async

c - 为什么要使用pthread_exit?

c - 如果 char 按标准为 1,为什么要写 `sizeof(char)`?

自定义压缩算法

multithreading - 如果调用 `pthread_join ()` 的线程被取消,那么目标线程将保持可连接状态

PHP:线程代理共享一个公共(public)对象

c - 为什么求和 floats 到一个 int temporary 运行比当一切都是 int 时慢得多?