请问多个子线程退出,父进程应该怎样回收资源

请问多个子线程退出,父进程应该怎样回收资源

父进程创建多个消费者线程和生产者线程,功能是实现了,但是子线程退出后,父进程在回收资源的时候停住了。

问题点就是:for循环中使用join等待线程退出导致main函数无法结束,我看作业区的代码也和我一样的问题。

还有同学是使用 线程分离(detached)让操作系统回收资源,但是他那样写又不阻塞,main函数执行完就退出程序了,所以那种代码写的也有问题。
图片描述

附上代码:

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

// 多对多的线程生产关系(线程同步与条件变量)

static int number = 0;           // 条件变量
static int total_of_produce = 0; // 总的生产产品的数量
static int total_of_consume = 0; // 总的消费产品的数量
static bool done = false;        // 结束消费者进程条件

static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void *thread_producer(void *arg)
{
    int cnt = atoi((char *)arg);
    int i, tmp;

    for (i = 0; i < cnt; i++)
    {

        pthread_mutex_lock(&mtx);

        printf("线程 [%ld] 生产一个产品,产品数量为:%d\n", pthread_self(), ++number);

        pthread_mutex_unlock(&mtx);
        pthread_cond_signal(&cond); // 唤醒消费者线程
    }

    pthread_exit((void *)0);
}

void *thread_consume(void *arg)
{
    for (;;)
    {
        pthread_mutex_lock(&mtx);

        while (number == 0) // 当产品数量为 0时,让线程阻塞,并释放锁,这里一般设置循环,防止没有重新获取到锁
            pthread_cond_wait(&cond, &mtx);

        while (number > 0)
        {
            total_of_consume++; // 消费产品总数
            printf("消费一个产品,剩余产品数量为:%d\n", --number);
            done = total_of_consume >= total_of_produce; // 判断消费者数量与产品数量
        }

        pthread_mutex_unlock(&mtx); // 消费者消费完成之后,释放锁

        if (done)
            break;
    }

    pthread_exit((void *)0);
}

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        fprintf(stderr, "Usage : run programe <%s> args less than 2.\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    pthread_t produce_tid[argc - 1];
    pthread_t consume_tid[argc - 1];

    int i = 0;
    int err = 0;

    for (i = 1; i < argc; i++)
    {
        total_of_produce += atoi(argv[i]); // 生产数量的总和

        // 创建多个生产者线程
        err = pthread_create(&produce_tid[i - 1], NULL, thread_producer, (void *)argv[i]);
        if (err != 0)
        {
            perror("[ERROR] pthread_create(): ");
            exit(EXIT_FAILURE);
        }

        // 创建多个消费者线程
        err = pthread_create(&consume_tid[i - 1], NULL, thread_consume, NULL);
        if (err != 0)
        {
            perror("[ERROR] pthread_create(): ");
            exit(EXIT_FAILURE);
        }

    }

    for (i = 0; i < argc - 1; i++)
    {
        pthread_join(produce_tid[i], NULL);
        pthread_join(consume_tid[i], NULL);
    }

    return 0;
}

正在回答

登陆购买课程后可参与讨论,去登陆

1回答

退出代码是没有任何问题的,这里发生这个原因的主要问题如下:

  多个消费者线程是并发关系,并非按照顺序去消费产品,这就会导致一个情况,一些线程会消费产品,则会继续执行后续的判断条件,就是看下当前消费总数是否已经大于等于生成总数 ,而另外一给些线程因为没有进行消费,而一直阻塞在条件变量处,这样就会在所有生成产品后,number == 0,一直阻塞在条件变量处理,

这里的解决访问如下:

   1. 条件作如下修改

    while (number == 0 && total_of_consume < total_of_produce) 
		{
			pthread_cond_wait(&cond, &mtx);
		}

在消费总数大于等于产生总数时,则无需再次阻塞在条件变量处

  2.在唤醒时就不要值换新一个线程,要唤醒所有线程,这样所有的线程都会去判断一下条件,否则就会导致一些线程一直没有唤醒,也就没有办法判断条件而退出

  for (i = 0; i < cnt; i++)
    {

        pthread_mutex_lock(&mtx);

        printf("线程 [%ld] 生产一个产品,产品数量为:%d\n", pthread_self(), ++number);

        pthread_mutex_unlock(&mtx);
        //pthread_cond_signal(&cond); // 唤醒消费者线程
		pthread_cond_broadcast(&cond);//这里是每次都唤醒所有阻塞在这个条件变量上的线程(一般为消费者线程)
    }


  • 慕小白0101 提问者 #1

    原来是消费者线程阻塞了!感谢无名老师

    2023-05-28 16:18:50
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星

相似问题

登录后可查看更多问答,登录/注册

请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师