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组件的相关 ...
随机推荐
- 【大数据技术】Sqoop
1.Sqoop是什么 Sqoop:SQL-to-Hadoop,传统数据库与Hadoop间数据同步工具.(MySQL.Oracle <==> HDFS.HBase.Hive) Sqoop ...
- spark on yarn 集群部署
概述 hadoop2.7.1 spark 1.5.1 192.168.31.62 resourcemanager, namenode, master 192.168.31.63 nodeman ...
- 用js检测文本框中输入的是否符合条件并有错误和正确提醒
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- MySQL高级知识(八)——ORDER BY优化
前言:在使用order by时,经常出现Using filesort,因此对于此类sql语句需尽力优化,使其尽量使用Using index. 0.准备 #1.创建test表. drop table i ...
- redis加锁
1. redis加锁分类 redis能用的的加锁命令分表是INCR.SETNX.SET2. 第一种锁命令INCR 这种加锁的思路是, key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 ...
- mongodb创建用户(转发)
参考文档: https://www.cnblogs.com/itxiongwei/p/5520863.html MongoDB 缺省是没有设置鉴权的,业界大部分使用 MongoDB 的项目也没有设置访 ...
- spring-config的坑
背景 1.修改配置中心读取配置文件的分支,配置了spring.cloud.config.label后,报错,异常大概是读取本地配置文件异常 解决 反复尝试了之后,发现是配置仓库的配置文件格式(yml) ...
- mysql备份命令
mysql备份命令如下: 备份多个数据库可以使用如下命令: mysqldump -uroot -p123456 --databases test1 test2 test3 > /home/tes ...
- 理论篇-MySQL知识汇总
1. 唯一索引 普通索引允许被索引的数据列包含重复的值.唯一索引则是不允许有重复的值,当然 null 除外,唯一索引不仅仅可以存储 null , 还可以存储多个 null.这么做的好处是: 简化了My ...
- DOM(三)
Text类型 文本节点由Text类型表示,包含的是可以照字面解释的纯文本内容,纯文本中可以包含转义后的HTML字符,但不包含HTML代码,Text节点具有以下特征: nodeType值为3: node ...