请问多个子线程退出,父进程应该怎样回收资源
父进程创建多个消费者线程和生产者线程,功能是实现了,但是子线程退出后,父进程在回收资源的时候停住了。
问题点就是: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;
}
18
收起
正在回答
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);//这里是每次都唤醒所有阻塞在这个条件变量上的线程(一般为消费者线程) }
物联网/嵌入式工程师
- 参与学习 394 人
- 提交作业 23204 份
- 解答问题 1175 个
行业热门,政策风口,人才缺口极大,现在入场时机正好! 上千人检验,数轮迭代的硬核知识体系,软硬件通吃 保姆式教学+简历指导+1V1模拟面试+3次内推,助力轻松就业!
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星