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组件的相关 ...
随机推荐
- js开发打印证书功能(二)
在上一篇的基础上,实现了一下另外一种方式. 上一篇地址:https://www.cnblogs.com/ljwsyt/p/9525290.html 首先,该方式也是有几种方法. 1.在上一篇的基础上, ...
- oracle windows 新建用户授权 导出导入bmp文件
1.新建用户 sqlplus /no log conn /as sysdba create user tkjj identified by tkjj2017 grant dba to tkjj con ...
- PHP到底有多牛?你所知道的网站都在用它
PHP到底有多牛?你所知道的网站都在用它 提起PHP,很多人的第一印象就是网站开发,确实,在网站开发方面,PHP难逢对手,当之无愧是“世界上最好的语言”. 有数据显示,目前全球5000万互联网网站中, ...
- Linux的目录结构--一切从根开始
Linux目录结构的特点 # 举例-linux下面使用光盘 ###.把光盘放入到光驱中 ###.linux中使用光盘 /dev/cdrom [root@oldboyedu- ~]# ll /dev/c ...
- 《JAVA程序设计》_第二周学习总结
20175217吴一凡 一.IDEA的安装和使用 参考老师的教程Intellj IDEA 简易教程. 1.IDEA的安装 因为我已经习惯了在Linux上敲代码,所以我决定将IDEA安装在虚拟机上. 首 ...
- spring程序打包使用该插件,不然容易报错xsd找不到
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade ...
- 使用ECharts来实现地图下钻功能(某省的市级下钻到县级)
var cityMap = { "长沙市": "430100", "株洲市": "430200", "湘潭市& ...
- Python:Day26 socket
SOCKET通信流程 服务器创建套接字链接: 1.创建SOCKET,socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=No ...
- day04 if判断、while条件循环、for迭代器循环部分使用举例
一:if判断 1.成绩>=90,那么:优秀 如果成绩>=80且<90,那么:良好 如果成绩>=70且<80,那么:普通 其 ...
- node.js使用express框架进行文件上传
关于node.js使用express框架进行文件上传,主要来自于最近对Settings-Sync插件做的研究.目前的研究算是取得的比较好的进展.Settings-Sync中通过快捷键上传文件,其实主要 ...