当一些异步的任务的时候,使用C++来创建线程来做任务的时候,

可以引用std::thread这个库

使用方法如下,创建一个线程,里面通过std::bind来绑定方法任务。

std::thread thread = std::thread(std::bind(&类名::方法名,this 参数);

这只是初始化线程

thread.join()

等着线程执行完成之后,主线程才能执行下去,此时主线程会立刻释放子线程占用的资源

thread.detach()

主线程不需要等待子线程执行完成,主线程和子线程分离

这是简单的线程调用,而C++中并没封装好线程池给我们使用。这里网上找了一个例子,可以简单看看注释。

#include

#include

#include

#include

#include

#include

#include

#include

#ifndef THREAD_POOL_H

#define THREAD_POOL_H

namespace std { //声明std的作用域

#define MAX_THREAD_NUM = 256

class MagicThreadPool {

public:

//内联函数,

inline MagicThreadPool(unsigned short size = 4) : stoped{false} {

//线程池大小

idlThrNum = size < 1 ? 1 : size;

for (size = 0; size < idlThrNum; ++size) { //初始化线程数量

// 只有一次构造函数,不调用拷贝构造函数,速度最快

pool.emplace_back(

[this] { // 工作线程函数

while (!this->stoped) {

//声明任务

std::function task;

{ // 获取一个待执行的 task

std::unique_lock<:mutex> lock{this->m_lock};// unique_lock 相比 lock_guard 的好处是:可以随时 unlock() 和 lock()

this->cv_task.wait(lock,

[this] {

return this->stoped.load() ||

!this->tasks.empty();

}

); // wait 直到有 task

if (this->stoped && this->tasks.empty())

return false;

task = std::move(this->tasks.front()); // 取一个 task

this->tasks.pop();

}

idlThrNum--;

//运行任务

task();

idlThrNum++;

}

}

);

}

}

//析构函数

inline ~MagicThreadPool() {

//停止全部任务

stoped.store(true);

cv_task.notify_all(); // 唤醒所有线程执行

for (std::thread &thread : pool) {

//thread.detach(); // 让线程“自生自灭”

if (thread.joinable())

thread.join(); // 等待任务结束, 前提:线程一定会执行完

}

}

//模板,需要声明类的类型,自动匹配返回值

template

auto commit(F &&f, Args &&... args) -> std::future {

//直接停止任务

if (stoped.load()) // stop == true ??

throw std::runtime_error("commit on ThreadPool is stopped.");

using RetType = decltype(f(

args...)); // typename std::result_of::type, 函数 f 的返回值类型

//自动返回值

auto task = std::make_shared<:packaged_task> >(

std::bind(std::forward(f), std::forward(args)...)

); // wtf !

std::future future = task->get_future();

{ // 添加任务到队列

std::lock_guard<:mutex> lock{

m_lock};//对当前块的语句加锁 lock_guard 是 mutex 的 stack 封装类,构造的时候 lock(),析构的时候 unlock()

tasks.emplace( //放入任务到任务池

[task]() { // push(Task{...})

(*task)();

}

);

}

cv_task.notify_one(); // 唤醒一个线程执行

return future;

};

//空闲线程数量

int idlCount() { return idlThrNum; }

private:

using Task = std::function;

//线程池

std::vector<:thread> pool;

//任务队列

std::queue tasks;

//同步锁

std::mutex m_lock;

std::condition_variable cv_task;

std::atomic stoped;

std::atomic idlThrNum;

};

}

#endif

使用方式,这类方法需要声明为static调用的方法

pool->commit(类名::方法名,参数);

这里注意一定不要这里是一个MagicThreadPool.h文件,千万别想因为代码好看分成两个h和cpp来写。

因为cpp将会编译好的代码,是无法更改的,无法进行模板在线程调用方法中的参数推导。会无法编译通过。

如果想看具体的流程可以看我MagicCamera3的代码

地址是MagicCamera3 https://github.com/cangwang/MagicCamera3,欢迎大家下载和点赞,如果有问题,也可以进我的组件化群1和群2,来讨论问题。

android jni 多线程,[Android]JNI进阶--线程池相关推荐

  1. C#多线程学习(四) 多线程的自动管理(线程池) (转载系列)——继续搜索引擎研究...

    在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPo ...

  2. 多线程编程学习笔记——线程池(二)

    接上文 多线程编程学习笔记--线程池(一) 三.线程池与并行度 此示例是学习如何应用线程池实现大量的操作,及与创建大量线程进行工作的区别. 1. 代码如下 using System; using Sy ...

  3. 多线程编程定长线程池

    多线程编程 定长线程池,可控制线程最大并发数,超出的线程会在队列中等待 Executors的方式创建定长线程池(不推荐容易,容易内存溢出OOM) ThreadPoolExecutor构造函数创建定长线 ...

  4. 【python爬虫学习记录 持续更新】多线程多进程,带线程池爬取实例

    文章目录 简介 多线程codingFrame 多进程codingFrame 线程池与进程池 线程池爬取实例(主页url隐了 主要看思路 和如何使用线程池框架) 简介 进程是资源单位 线程是执行单位 每 ...

  5. Android中常见的4种线程池的理解(转)

    转:https://blog.csdn.net/l540675759/article/details/62230562 转:https://blog.csdn.net/seu_calvin/artic ...

  6. Android开发——Android中常见的4种线程池(保证你能看懂并理解)

    0.前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52415337 使用线程池可以给我们带来很多好处,首先通过线程池中线程的重用 ...

  7. Android通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比

    在加载大量数据的时候,经常会用到异步加载,所谓异步加载,就是把耗时的工作放到子线程里执行,当数据加载完毕的时候再到主线程进行UI刷新.在数据量非常大的情况下,我们通常会使用两种技术来进行异步加载,一是 ...

  8. Android中网络请求创建单个线程池的方法

    创建单个线程池的方法 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; impor ...

  9. android java 多线程,Android多线程的四种方式

    当我们启动一个App的时候,Android系统会启动一个Linux Process,该Process包含一个Thread,称为UI Thread或Main Thread.通常一个应用的所有组件都运行在 ...

最新文章

  1. 一次 MySQL 千万级大表的优化过程
  2. 系列文章|OKR与敏捷(二):实现全栈敏捷
  3. 【android-tips】installfailedinsufficientstorage解决方案
  4. python 多进程 multiprocessing 进程池pool报错 in join assert self._state in (CLOSE, TERMINATE) AssertionError
  5. C++ : 构造函数,拷贝构造函数,移动构造函数,拷贝赋值运算符,移动赋值运算符应用场景
  6. php输出mysqli查询出来的结果
  7. Linux操作(4)—— 如何安装或卸载软件
  8. Gemini论文笔记
  9. qt5.11 linux oracle,Qt5.11.1 + VS2017环境搭建(Qt5.11在windows上的安装)
  10. Android 开源框架 ( 二 ) 基于OkHttp进一步封装的okhttp-utils介绍
  11. linux主机重启之后,报UNEXPECTED INCOMSISTEMCY:RUN fsck MANUALLY.
  12. 计算机组成原理——基础知识
  13. 数据结构_郝斌老师自学大纲
  14. 在Ubuntu 18.04中安装ROS操作系统
  15. 棉猴论坛VIP之驱动基础系列教程 视频教程
  16. 告别乐盲,AI 通过歌词生成旋律【智能快讯】
  17. 【地平线旭日X3派试用体验】变身红白机玩转NES游戏
  18. FFmpeg系列(五)—— 音频重采样
  19. ccf计算机认证考试题集,【计算机本科补全计划】CCF计算机职业资格认证 2017-03 试题初试...
  20. 欧姆龙NJ/NX基于Sysmac Studio的EIP通讯 方式

热门文章

  1. ASP.NET MVC2用户界面的巨大改变
  2. C++ 领域:游戏、HPC、编译器、金融、财务
  3. 虚拟机卡在登录界面卡住了_手机都10核了 为何还是照样卡?
  4. em算法 实例 正态分布_人人都能看懂的EM算法推导
  5. xstream-0 使用入门
  6. html5新增的一个input属性
  7. 团体程序设计天梯赛-练习集-L1-046. 整除光棍
  8. Spring中的AOP和属性注入
  9. Delphi插件创建、调试与使用应用程序扩展
  10. CSS hack——不同浏览器的CSS应对法