cpp11_thread线程
一、进程与线程
cpu一般有m核n线程的说法,那么该cpu只能同时运行n个线程(线程中没有sleep)。
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <vector>
#include <GSLAM/core/Glog.h>
#include <GSLAM/core/Mutex.h>
void simple_threadfunc()
{
LOG(INFO)<<"Simple thread function.";
}
void simple_pooledfunc(int i){
LOG(INFO)<<"Thread "<<i<<", ID:"<<std::this_thread::get_id();
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
class MultiReadWrite{
public:
std::vector<int> _vec;
std::mutex _mutex;
std::atomic<bool> _shouldStop;
std::vector<std::thread> _threads;
MultiReadWrite(){
_shouldStop=false;
for(int i=0;i<2;i++)
_threads.push_back(std::thread(&MultiReadWrite::writeThread,this));
for(int i=0;i<2;i++)
_threads.push_back(std::thread(&MultiReadWrite::readThread,this));
for(int i=0;i<2;i++)
_threads.push_back(std::thread(&MultiReadWrite::deleteThread,this));
}
~MultiReadWrite(){
_shouldStop=true;
for(auto& t:_threads) t.join();
}
void writeThread(){
for(int i=0;!_shouldStop;i++)
{
_mutex.lock();
if(_vec.size()<100)
_vec.push_back(i);
_mutex.unlock();
std::this_thread::sleep_for(std::chrono::microseconds(5));
}
}
void readThread(){
while(!_shouldStop)
{
{
std::unique_lock<std::mutex> lock(_mutex);
if(_vec.size())
LOG(INFO)<<std::this_thread::get_id()<<" get "<<_vec.back();
}
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
void deleteThread(){
while(!_shouldStop){
{ std::unique_lock<std::mutex> lock(_mutex);
if(_vec.size()>1)
_vec.pop_back();
}
std::this_thread::sleep_for(std::chrono::microseconds(5));
}
}
};
class ConditionPool
{
public:
std::mutex _mutex;
std::condition_variable _condition;
std::vector<std::thread> _threads;
bool _ready;
ConditionPool(int thread_num=4){
_ready=false;
for(int i=0;i<thread_num;i++)
_threads.push_back(std::thread(&ConditionPool::process,this));
}
~ConditionPool(){
_condition.notify_all();
for(auto& t:_threads) t.join();
}
void process() {
std::unique_lock<std::mutex> lck(_mutex);
while (!_ready)
_condition.wait(lck);
LOG(INFO) << "thread " << std::this_thread::get_id();
}
void go() {
std::unique_lock<std::mutex> lck(_mutex);
_ready = true;
_condition.notify_all();
}
};
// A simple threadpool implementation.
class ThreadPool {
public:
// All the threads are created upon construction.
explicit ThreadPool(const int num_threads): stop(false) {
CHECK_GE(num_threads, 1)
<< "The number of threads specified to the ThreadPool is insufficient.";
for (size_t i = 0; i < num_threads; ++i) {
workers.emplace_back([this] {
for (;;) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.wait(lock, [this] {
return this->stop || !this->tasks.empty();
});
if (this->stop && this->tasks.empty()) return;
task = std::move(this->tasks.front());
this->tasks.pop();
}
task();
}
});
}
}
~ThreadPool(){
{
std::unique_lock<std::mutex> lock(queue_mutex);
stop = true;
}
condition.notify_all();
for (std::thread& worker : workers)
worker.join();
}
// Adds a task to the threadpool.
template <class F, class... Args>
auto Add(F&& f, Args&& ... args)
->std::future<typename std::result_of<F(Args...)>::type>;
private:
// Keep track of threads so we can join them
std::vector<std::thread> workers;
// The task queue
std::queue<std::function<void()> > tasks;
// Synchronization
std::mutex queue_mutex;
std::condition_variable condition;
bool stop;
};
// add new work item to the pool
template <class F, class... Args>
auto ThreadPool::Add(F&& f, Args&& ... args)
->std::future<typename std::result_of<F(Args...)>::type> {
using return_type = typename std::result_of<F(Args...)>::type;
auto task = std::make_shared<std::packaged_task<return_type()> >(
std::bind(std::forward<F>(f), std::forward<Args>(args)...));
std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);
// don't allow enqueueing after stopping the pool
CHECK(!stop) << "The ThreadPool object has been destroyed! Cannot add more "
"tasks to the ThreadPool!";
tasks.emplace([task]() {
(*task)();
});
}
condition.notify_one();
return res;
}
int cpp11_thread()
{
// simple thread call
std::thread thread1(simple_threadfunc);
thread1.join();
// simple thread with lamda func
std::vector<int> vec(4,10);
std::thread thread2([&vec]{for(auto i:vec) vec[0]+=i;});
thread2.join();
LOG(INFO)<<vec[0];
// simple thread pool
std::vector<std::thread> threads(4);
for(int i=0;i<threads.size();i++)
threads[i]=std::thread(simple_pooledfunc,i);
for(auto& thread:threads) thread.join();
// simple multi readwrite, mutex
{
MultiReadWrite mutexTest;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// simple condition usage
ConditionPool conditionPool(4);
conditionPool.go();
// thread pool with future return
ThreadPool pool(4);
std::vector<int> vec1(4,10);
auto result=pool.Add([vec1]{int sum=0;for(auto i:vec1) sum+=i;return sum;});
result.wait();
LOG(INFO)<<"sum is "<<result.get();
}
cpp11_thread线程的更多相关文章
- C++11下的线程池以及灵活的functional + bind + lamda
利用boost的thread实现一个线程类,维护一个任务队列,以便可以承载非常灵活的调用.这个线程类可以方便的为后面的线程池打好基础.线程池还是动态均衡,没有什么别的.由于minGW 4.7 对 C+ ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- [高并发]Java高并发编程系列开山篇--线程实现
Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- Java 线程
线程:线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须拥有一个父进程.线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源.它与父进程的其他线程共享该进程的所有资 ...
- C++实现线程安全的单例模式
在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...
- 记一次tomcat线程创建异常调优:unable to create new native thread
测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...
- Android线程管理之ThreadLocal理解及应用场景
前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...
- C#多线程之线程池篇3
在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...
随机推荐
- Java中String对象两种赋值方式的区别
本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...
- Jenkins+Ansible+Gitlab自动化部署三剑客-Jenkins本地搭建
后面需要shell基础,目前没有,等有了,再更
- 使用vue-cli脚手架创建项目
ue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目. GitHub地址是:https://github.com/vuejs/vue-cli 一.安 ...
- 转://Oracle A用户给B用户授权查询指定表或视图权限方案
用DNINMSV31账户登录数据库进行如下操作: CREATE USER NORTHBOUND IDENTIFIED BY NORTHBOUND DEFAULT TABLESPACE "TB ...
- 【转】OS X Base System 上没有足够的空间来进行安装
今天在windows环境下安装IOS虚拟机,安装过程中报了一个错:“OS X Base System ”上没有足够的空间来进行安装.如图: 之后的解决办法是:点击上方的[实用工具]->[磁盘工具 ...
- range()函数
range()函数 函数说明: range(start, stop[, step]) -> range object,根据start与stop指定的范围以及step设定的步长,生成一个序列.参数 ...
- python相关资料链接
后续的博客更新,会涉及到很多的python及python的框架相关的内容,这里将自己收藏的一些关于python相关资料的链接做一个整理,算是一个导航索引吧... PS:其中有些链接对应的技术团队文章, ...
- IDE安装Lombok插件提高开发效率
Lombok官方api:https://projectlombok.org/features/index.html 使用lombok之后,省去了许多没必要的get,set,toString,equal ...
- 【转】MySQL中的行级锁,表级锁,页级锁
在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 在数据库的锁机制中介绍过,在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引 ...
- [Spark][Python][RDD][DataFrame]从 RDD 构造 DataFrame 例子
[Spark][Python][RDD][DataFrame]从 RDD 构造 DataFrame 例子 from pyspark.sql.types import * schema = Struct ...