Pthread producer-consumer problem

requirements:
it"s simple to practice using pthread to implement the producer-consumer model

  1. create a data_queue.c, for caching data
  2. main thread for creating producer and consumer threads

question

  1. Click the Start button for the first time to execute the start (), program and execute normally
  2. Click the Stop button to execute the log normal print thread exit information in the stop (), program
  3. Click the start button again, and execute the start (), producer and consumer thread to print production data and consumption data only once, and then get stuck there. I don"t know if it"s a deadlock?

the code is as follows:

Code is simplified
  • data_queue.c
static pthread_t producer;
static pthread_t consumer;
static int finished_producer = 0;
static int finished_consumer = 0;

void *producer_run(void *userdata) {
    LOGE("...\n");
    StudentQueue *queue = (StudentQueue *) userdata;
    int age = 0;
    while (1) {
        Student student;
        student.age = agePP;
        sprintf(student.name, "name ... %d", student.age);
        LOGI("Producer: {age: %d, name: %s}", student.age, student.name);
        student_queue_put(queue, student);
        sleep(1);
        if (finished_producer) {
            Status *status = (Status *) malloc(sizeof(Status));
            status->code = 1001;
            status->msg = "";
            status->opaque = queue;
            pthread_exit((void *) status);
        }
    }
}

void *consumer_run(void *userdata) {
    LOGE("...\n");
    StudentQueue *queue = (StudentQueue *) userdata;
    while (1) {
        Student student;
        student_queue_get(queue, &student);
        sleep(1);
        LOGE("Consumer: {age: %d, name: %s}", student.age, student.name);
        if (finished_consumer) {
            Status *status = (Status *) malloc(sizeof(Status));
            status->code = 1001;
            status->msg = "";
            status->opaque = queue;
            pthread_exit((void *) status);
        }
    }
}

extern "C"
JNIEXPORT void JNICALL
Java_me_learn_JNIThread_start(JNIEnv *env, jobject instance) {
    StudentQueue *queue = (StudentQueue *) malloc(sizeof(StudentQueue));
    student_queue_init(queue);

    pthread_create(&producer, NULL, producer_run, (void *) queue);
    pthread_setname_np(producer, "producer");
    pthread_create(&consumer, NULL, consumer_run, (void *) queue);
    pthread_setname_np(consumer, "consumer");
}

extern "C"
JNIEXPORT void JNICALL
Java_me_learn_JNIThread_stop(JNIEnv *env, jobject instance) {
    finished_producer = 1;
    finished_consumer = 1;

    void *status_producer;
    pthread_join(producer, &status_producer);
    Status *ret_producer = (Status *) status_producer;
    LOGE("[%d]: %s", ret_producer->code, ret_producer->msg);
    free(ret_producer);

    void *status_consumer;
    pthread_join(consumer, &status_consumer);
    Status *ret_consumer = (Status *) status_consumer;
    LOGE("[%d]: %s", ret_consumer->code, ret_consumer->msg);
    free(ret_consumer);

    student_queue_destroy((StudentQueue *) ret_consumer->opaque);

    producer = 0;
    consumer = 0;
}
Jun.18,2021

well, I'm being silly. After setting the finish logo to 1, I didn't reset it to 0 when I start again.

Menu