并发程序设计--D10线程池及gdb调试多线程

线程池

概念:

通俗的讲就是一个线程的池子,可以循环的完成任务的一组线程集合

必要性:

我们平时创建一个线程,完成某一个任务,等待线程的退出。但当需要创建大量的线程时,假设T1创建线程时间,T2为在线程任务执行时间,T3线程销毁时间当 T1+T3 > T2,这时候就不划算了,使用线程池可以降低频繁创建和销毁线程所带来的开销,任务处理时间比较短的时候这个好处非常显著

线程池的基本结构:

1 任务队列,存储需要处理的任务,由工作线程来处理这些任务

2 线程池工作线程,它是任务队列任务的消费者,等待新任务的信号

线程池的实现:

1、创建线程池的基本结构:

任务队列链表

typedef struct Task;

线程池结构体

typedef struct ThreadPool;

2、线程池的初始化:

pool_init()

{

创建一个线程池结构

实现任务队列互斥锁和条件变量的初始化

创建n个工作线程

}

3、线程池添加任务

   pool_add_task

{

    判断是否有空闲的工作线程

    给任务队列添加一个节点

    给工作线程发送信号newtask

}

4、实现工作线程

   workThread

{

while(1){

   等待newtask任务信号

   从任务队列中删除节点

   执行任务

}

}

5、线程池的销毁

   pool_destory

{

    删除任务队列链表所有节点,释放空间

    删除所有的互斥锁条件变量

    删除线程池,释放空间

}

编译错误:

error: ‘ThreadPool {aka struct ThreadPool}’ has no member named ‘head’

意义:ThreadPool 结构体没有head这个成员。

解决:检查是否拼写错误。

error: too few arguments to function ‘pthread_mutex_init’

意思:pthread_mutex_init这个函数参数少了

解决:检查函数的参数,添加对应的参数

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>#define POOL_NUM 10
typedef struct Task{void *(*func)(void *arg);void *arg;struct Task *next;
}Task;typedef struct ThreadPool{pthread_mutex_t taskLock;pthread_cond_t newTask;pthread_t tid[POOL_NUM];Task *queue_head;int busywork;}ThreadPool;ThreadPool *pool;void *workThread(void *arg){while(1){pthread_mutex_lock(&pool->taskLock);pthread_cond_wait(&pool->newTask,&pool->taskLock);Task *ptask = pool->queue_head;pool->queue_head = pool->queue_head->next;pthread_mutex_unlock(&pool->taskLock);ptask->func(ptask->arg);pool->busywork--;}}void *realwork(void *arg){printf("Finish work %d\n",(int)arg);}void pool_add_task(int arg){Task *newTask;pthread_mutex_lock(&pool->taskLock);while(pool->busywork>=POOL_NUM){pthread_mutex_unlock(&pool->taskLock);usleep(10000);pthread_mutex_lock(&pool->taskLock);}pthread_mutex_unlock(&pool->taskLock);newTask = malloc(sizeof(Task));newTask->func =  realwork;newTask->arg = arg;pthread_mutex_lock(&pool->taskLock);Task *member = pool->queue_head;if(member==NULL){pool->queue_head = newTask;}else{while(member->next!=NULL){member=member->next;}member->next = newTask;}pool->busywork++;pthread_cond_signal(&pool->newTask);pthread_mutex_unlock(&pool->taskLock);}void pool_init(){pool = malloc(sizeof(ThreadPool));pthread_mutex_init(&pool->taskLock,NULL);pthread_cond_init(&pool->newTask,NULL);pool->queue_head = NULL;pool->busywork=0;for(int i=0;i<POOL_NUM;i++){pthread_create(&pool->tid[i],NULL,workThread,NULL);}
}void pool_destory(){Task *head;while(pool->queue_head!=NULL){head = pool->queue_head;pool->queue_head = pool->queue_head->next;free(head);}pthread_mutex_destroy(&pool->taskLock);pthread_cond_destroy(&pool->newTask);free(pool);}
int main(){pool_init();sleep(20);for(int i=1;i<=20;i++){pool_add_task(i);}sleep(5);pool_destory();}

线程的GDB调试

显示线程

info thread

切换线程

thread id

GDB为特定线程设置断点

break location thread id

GDB设置线程锁,

set scheduler-locking on/off

on:其他线程会暂停。可以单独调试一个线程

#include <pthread.h>
#include <stdio.h>void *testThread(void *arg){char *threadName = (char*)arg;printf("Current running %s\n",threadName);printf("aaaaaaaa\n");printf("bbbbbbbb\n");pthread_exit(0);}int main(){pthread_t tid1,tid2;pthread_create(&tid1,NULL,testThread,"thread1");pthread_create(&tid2,NULL,testThread,"thread2");pthread_join(tid1,NULL);pthread_join(tid2,NULL);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/608736.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

贯穿设计模式-中介模式+模版模式

样例代码 涉及到的项目样例代码均可以从https://github.com/WeiXiao-Hyy/Design-Patterns.git获取 需求 购买商品时会存在着朋友代付的场景&#xff0c;可以抽象为购买者&#xff0c;支付者和中介者之间的关系 -> 中介者模式下单&#xff0c;支付&#xff0c;发货&#xff0…

VR思政情景实训教学

在传统的思政教育中&#xff0c;学生通常是通过课本阅读和讲堂听讲来获取知识。虽然这种方式可以传递基础知识&#xff0c;但对于学生的思维开拓和情感体验存在一定的局限性。而VR思政情景实训教学应用则能够打破这种传统方式的限制&#xff0c;为学生提供沉浸式的学习体验。 通…

什么是软件测试

一、软件测试的定义 软件测试的经典定义是在规定条件下对程序进行操作&#xff0c;以发现错误&#xff0c;对软件质量进行评估。因为软件是由文档、数据以及程序组成的&#xff0c;所以软件测试的对象也就不仅仅是程序本身&#xff0c;而是包括软件形成过程的文档、数据以及程…

什么是博若莱新酒节?

在红酒圈儿里混&#xff0c;一定不能不知道博若莱新酒节&#xff0c;这是法国举世闻名的以酒为主题的重要节日之一。现已成为世界范围内庆祝当年葡萄收获和酿制的节日&#xff0c;被称为一年一度的酒迷盛会。 云仓酒庄的品牌雷盛红酒LEESON分享博若莱位于法国勃艮第南部&#x…

Spark Core------算子介绍

RDD基本介绍 什么是RDD RDD:英文全称Resilient Distributed Dataset&#xff0c;叫做弹性分布式数据集&#xff0c;是Spark中最基本的数据抽象&#xff0c;代表一个不可变、可分区、里面的元素可并行计算的集合。 Resilient弹性&#xff1a;RDD的数据可以存储在内存或者磁盘…

R语言【utils】——stack():从数据帧或列表中堆叠或解堆叠向量

Package utils version 4.2.0 Description 堆叠向量将多个向量连接成单个向量&#xff0c;并加上一个指示每个观察来源的因子。解除堆叠将反转此操作。 Usage stack(x, ...) ## Default S3 method: stack(x, dropFALSE, ...) ## S3 method for class data.frame stack(x, sel…

LLM在社交媒体上应用的任务和挑战

文章把用户使用社交媒体的原因归结为搜寻知识、找乐子和基础性任务等三种。 基于此&#xff0c;把LLM应用在社交媒体的任务抽象为了&#xff1a; 知识任务&#xff1a;用户获取新信息、知识&#xff0c;比如通过搜索帖子、询问其他用户。娱乐任务&#xff1a;在社交媒体上获得…

Unity游戏引擎的未来进化展望

随着技术进步和社会需求的变化&#xff0c;游戏开发领域正以前所未有的速度发展&#xff0c;而作为全球最受欢迎的游戏引擎之一&#xff0c;Unity无疑将在未来扮演着至关重要的角色。本文旨在探讨Unity游戏引擎在未来可能的进化方向以及其对整个行业的影响。 一、图形与视觉效…

c++ std::move()到底干了什么

每次用到或者看到std::move() &#xff0c;总会被它的名字误导&#xff0c;以为是发生了数据所有权的移动。然而实际上&#xff0c;std::move()啥都没干&#xff0c;只是改变了其入参的属性&#xff0c;让它成为了一个右值。 std::move() 是 C 中一个很有用的函数&#xff0c;…

C# OpenCvSharp DNN FreeYOLO 目标检测

目录 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN FreeYOLO 目标检测 效果 模型信息 Inputs ------------------------- name&#xff1a;input tensor&#xff1a;Float[1, 3, 192, 320] --------------------------------------------------------------- Outp…

Eureka注册中心Eureka提供者与消费者,Eureka原理分析,创建EurekaServer和注册user-service

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Eureka提供者与消费者二、Eureka原理分析eurekaeureka的作用eureka总结 三、创建EurekaServer和注册user-service创建EurekaServer总结 服务的拉取总结-Eur…

docker拉取镜像提示 remote trust data does not exist for xxxxxx

1、How can I be sure that I am pulling a trusted image from docker 2、docker: you are not authorized to perform this operation: server returned 401. 以上两个问题可以试试以下解决办法 DOCKER_CONTENT_TRUSTfalse 本人是使用jenkins部署自己的项目到docker容器出现…

关于 java 语言中的 package 和 import 机制

关于 java 语言中的 package 和 import 机制&#xff1a; 1、为什么要使用 package&#xff1f; package 是java中包机制。包机制的作用是为了方便程序的管理。 不同功能的类分别存放在不同的包下。&#xff08;按照功能划分的&#xff0c;不同的软件包具有不同的功能。&#x…

C#轻量级日志功能(只有一个类)

最近在开发基于.net6的一个数据监控软件&#xff0c;使用其它开源log库都有点麻烦&#xff0c;就想着对Console.WriteLine()方法重定向到文件&#xff0c;非常方便的实现日志记录功能&#xff0c;同时也不影响之前的代码结构。 public class LogTextWriter : TextWriter {publ…

Spring MVC参数接收、参数传递

Springmvc中&#xff0c;接收页面提交的数据是通过方法形参来接收&#xff1a; 处理器适配器调用springmvc使用反射将前端提交的参数传递给controller方法的形参 springmvc接收的参数都是String类型&#xff0c;所以spirngmvc提供了很多converter&#xff08;转换器&#xff0…

Contingency Planning学习记录

Contingency Planning over Probabilistic Hybrid Obstacle Predictions for Autonomous Road Vehicles Contingency Planning over Probabilistic Hybrid Obstacle Predictions for Autonomous Road Vehicles - 知乎 Contingency Planning over Probabilistic Hybrid Obstac…

QT第二天

使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否为&…

赠送葡萄酒:为别人选择合适的葡萄酒

葡萄酒可以在许多不同的场合成为很好的礼物&#xff0c;因为它可以用来庆祝许多不同的事情。当被邀请去别人家时&#xff0c;你可以带酒去吃饭。葡萄酒可以用来纪念婚礼、出生、毕业和各种纪念日&#xff0c;来自云仓酒庄品牌雷盛红酒分享这是一个非常合适的专业礼物。但是你怎…

1878_emacs company backend的选择尝试

Grey 全部学习内容汇总&#xff1a; GitHub - GreyZhang/editors_skills: Summary for some common editor skills I used. 1872_emacs company backend的选择尝试 从C语言开发的使用场景角度&#xff0c;通过测试尝试看看这个company的backend应该来如何配置。 主题由来介…

React Native 桥接原生实现 JS 调用原生方法

一、为什么需要桥接原生 为了满足在React 层无法实现的需求 复杂高性能的组件&#xff1a;复杂表格、视频播放原生层开发能力&#xff1a;传感器编程、widget平台属性&#xff1a;系统信息、设备信息对接第三方应用&#xff1a;相机、相册、地图 真实的开发过程中是不可能完…