pthreads的用C - 了pthread_exit [英] pthreads in C - pthread_exit

查看:139
本文介绍了pthreads的用C - 了pthread_exit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于某种原因,我认为,在主函数结束调用pthread_exit(NULL)将保证所有正在运行的线程(在主函数中至少创建)将完成运行前主可以退出。然而,当我运行,下面这个code,而不调用这两个在pthread_join功能(在主月底)明确,我得到一个分段错误,这似乎发生,因为两个线程完成他们的工作之前,主要的功能已经退出了,因此焦炭缓冲器不可用了。然而,当我包括主要结束这两个在pthread_join函数调用运行,因为它应该。为了保证主要将所有正在运行的线程都完成之前不会退出,是有必要明确调用在pthread_join直接在主初始化所有主题?

 的#include<&stdlib.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&pthreads.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&ASSERT.H GT;
#包括LT&;&semaphore.h GT;
#定义NUM_CHAR 1024
的#define BUFFER_SIZE 8typedef结构{
    pthread_mutex_t互斥;
    sem_t十足;
    sem_t空的;
    字符*缓冲区;
}上下文;void *的读卡器(无效* ARG){
    上下文语境* =(上下文*)ARG;
    的for(int i = 0; I< NUM_CHAR ++我){
        sem_wait(安培;上下文和GT;已满);
        的pthread_mutex_lock(及(上下文>互斥));
        焦C =上下文>缓冲区[我BUFFER_SIZE%];
        调用pthread_mutex_unlock(及(上下文>互斥));
        sem_post(安培;上下文和GT;空);        的printf(%C,C);
    }
    的printf(\\ n);
    返回NULL;
}void *的作家(无效* ARG){
    上下文语境* =(上下文*)ARG;
    的for(int i = 0; I< NUM_CHAR ++我){
        sem_wait(安培;上下文和GT;空);
        的pthread_mutex_lock(及(上下文>互斥));
        上下文>缓冲区[我BUFFER_SIZE%] ='A'+(兰特()%26);
        浮动ranFloat =(浮点)兰特()/ RAND_MAX;
        如果(ranFloat小于0.5)睡眠(0.2);
        调用pthread_mutex_unlock(及(上下文>互斥));
        sem_post(安培;上下文和GT;已满);
    }
    返回NULL;
}诠释主(){
    字符缓冲区[BUFFER_SIZE];
    读者的pthread_t,作家;
    上下文语境;
    函数srand(时间(NULL));
    INT状态= 0;
    状态=调用pthread_mutex_init(安培; context.mutex,NULL);
    状态= sem_init(安培; context.full,0,0);
    状态= sem_init(安培; context.empty,0,BUFFER_SIZE);
    context.buffer =缓冲;    状态=在pthread_create(安培;读卡器,NULL,阅读器,与放大器;背景);
    状态=在pthread_create(安培;作家,NULL,作家,和放大器;背景);    在pthread_join(读者,NULL); //这线似乎是必要
    在pthread_join(作家,NULL); //这线似乎是必要    了pthread_exit(NULL);
    返回0;
}

如果是这种情况,我怎么能处理的情况下是大量相同的线程(如在下面的code)将使用相同​​的线程标识符创建?在这种情况下,我怎么能确保所有的线程将主要退出之前已经完成?难道我真的要保持NUM_STUDENTS的pthread_t标识符数组才能够做到这一点?我想我可以通过让学生线程发送一个信号量,然后让在该信号的主要功能等待做到这一点,但真的要做到这一点没有更简单的方法?

  INT的main()
{
    线程的pthread_t;
    的for(int i = 0; I< NUM_STUDENTS;我++)
        在pthread_create(安培;螺纹,NULL,学生,NULL); //线程
    //确保所有学生线程完成
    出口(0);
}


解决方案

了pthread_exit()是由一个线程调用,以终止其自身的执行功能。对于这种情况你给它不会从你的主程序线程调用。

当你想通了,在pthread_join()是正确的手段,从等待合并线程完成的main()

此外,你已经想通了,你需要保持从在pthread_create()返回的值传递给在pthread_join()

这意味着,如果你打算使用在pthread_join()的pthread_t 变量为您创建的所有线程code>。

相反,让你有每个线程的身份证复印件建的pthread_t 的数组。

For some reason I thought that calling pthread_exit(NULL) at the end of a main function would guarantee that all running threads (at least created in the main function) would finish running before main could exit. However when I run this code below without calling the two pthread_join functions (at the end of main) explicitly I get a segmentation fault, which seems to happen because the main function has been exited before the two threads finish their job, and therefore the char buffer is not available anymore. However when I include these two pthread_join function calls at the end of main it runs as it should. To guarantee that main will not exit before all running threads have finished, is it necessary to call pthread_join explicitly for all threads initialized directly in main?

#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;
}

If that is the case, how could I handle the case were plenty of identical threads (like in the code below) would be created using the same thread identifier? In that case, how can I make sure that all the threads will have finished before main exits? Do I really have to keep an array of NUM_STUDENTS pthread_t identifiers to be able to do this? I guess I could do this by letting the Student threads signal a semaphore and then let the main function wait on that semaphore, but is there really no easier way to do this?

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() is a function called by a thread to terminate its own execution. For the situation you've given it is not to be called from your main program thread.

As you have figured out, pthread_join() is the correct means to wait for the completion of a joinable thread from main().

Also as you've figured out, you need to maintain the value returned from pthread_create() to pass to pthread_join().

What this means is that you cannot use the same pthread_t variable for all the threads you create if you intend to use pthread_join().

Rather, build an array of pthread_t so that you have a copy of each thread's ID.

这篇关于pthreads的用C - 了pthread_exit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆