我想设置一个函数(或lambda函数)的调用,以便在当前线程退出时自动发生,但std::thread除非我接管线程创建的整个任务或手动确保,否则我看不到任何可行的方法.每个线程调用一些我总是提供的特定函数作为它的最后一个操作.
基本上,我想要的功能,其原型可能类似于这样的东西:
on_thread_exit(const std::function<void()> &func);
Run Code Online (Sandbox Code Playgroud)
当调用on_thread_exit的线程最终终止时,将执行必要的设置以确保自动调用给定函数,并且不需要在创建线程或终止时显式调用任何特定函数.
有几种方法可以实现多线程.std::thread最终由C++ 11标准引入,但boost::thread可以有效地使用.每种技术都有特定的语法和内容,但是 - 粗略地 - 用于CPU并行编程.但它们有不同的效果.我知道,例如,MPI和OpenMP用于不同的内存模型.
我也知道技术的选择实际上并不是唯一的,因此可以使用另一种技术(再次,MPI和OpenMP).为什么它们被用于不同的效果但仍然使用相同的源(CPU)?
如果我根据每种技术编译具有并行性的C++程序,那么(从操作系统和硬件的角度来看)会有什么不同?例如,OpenMP还是std::thread使用POSIX线程?如果是这样,C++ 11的线程如何在Windows上运行?或者这些技术中的每一种都通过汇编语言直接与CPU协同工作?
我有一个类对象,在某些情况下只需要启动一个线程.在析构函数中,无论何时有线程都可以方便地知道.问题是,如何检测std :: thread对象是否是有效线程.
class MyClass
{
public:
~MyClass()
{
// Attention pseudocode!!!!!
if(mythread is a valid object)
mythread.join();
if(mythread was a valid object in its lifetime)
Do some stuff
}
void DoSomeStuff()
{
// May or may not create a thread
}
private:
std::thread mythread;
};
Run Code Online (Sandbox Code Playgroud) 我对构造std::thread对象的细节很感兴趣(并对此感到困惑)。根据cppreference,线程函数和所有参数都被值复制到一些线程可访问的存储中,然后调用。
1)这个线程可访问的存储究竟是什么?是不是语义上等同于某种线程本地存储,在线程函数返回后销毁变量?
2) 传递给线程函数时参数的值类别是什么?cppreference 上的描述表明它们作为左值传递(无论如何它们都被赋予了名称)。我对 GCC 和 clang 的测试似乎表明相反,即 r 值。具体来说,以下代码无法编译:
void f(int& a) {
std::cout << ++a << '\n';
}
int main() {
std::thread t(&f, 1);
t.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我们f改为
void f(int&& a) {
std::cout << ++a << '\n';
}
int main() {
std::thread t(&f, 1);
t.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
那么,标准对此有何看法?
余组Eclipse(实际上赛灵思SDK但基于Eclipse),和g ++ 4.9.2,编译其使用独立ASIO一个项目,我在属性使用-std = C++ 11 - > C/C++编译 - >设置 - >工具设置 - >其他标志,以便可以使用所有C++ 11功能进行编译.
我也在ASIO_HAS_STD_THREAD, ASIO_STANDALONEC/C++通用符号中设置等等,我希望ASIO标题std::thread代替使用pthread.但是,我仍然看到来自make的错误:
undefined reference to pthread_create,
..asio-1.10.6\include\asio\detail\impl\posix_thread.ipp
and posix_tss_ptr.hpp
Run Code Online (Sandbox Code Playgroud)
因此问题是,由于我使用C++ 11,和指定的ASIO_HAS_STD_THREAD但不是ASIO_HAS_PTHREADS,则posix_thread.ipp不应甚至包括(通过posix_thread.hpp),根据在ASIO thread.hpp:
#if !defined(ASIO_HAS_THREADS)
# include "asio/detail/null_thread.hpp"
#elif defined(ASIO_WINDOWS)
# if defined(UNDER_CE)
# include "asio/detail/wince_thread.hpp"
# else
# include "asio/detail/win_thread.hpp"
# endif
#elif defined(ASIO_HAS_PTHREADS)
# include "asio/detail/posix_thread.hpp"
#elif defined(ASIO_HAS_STD_THREAD)
# include "asio/detail/std_thread.hpp"
#else
# error Only Windows, POSIX and std::thread are supported! …Run Code Online (Sandbox Code Playgroud) 我std::thread在我的C++代码中使用一个不断轮询一些数据并将其添加到缓冲区.我使用a C++ lambda来启动这样的线程:
StartMyThread() {
thread_running = true;
the_thread = std::thread { [this] {
while(thread_running) {
GetData();
}
}};
}
Run Code Online (Sandbox Code Playgroud)
thread_running 是atomic<bool>在类头中声明的.这是我的GetData功能:
GetData() {
//Some heavy logic
}
Run Code Online (Sandbox Code Playgroud)
接下来我还有一个StopMyThread函数,我将其设置thread_running为false,以便它退出while中的while循环lambda block.
StopMyThread() {
thread_running = false;
the_thread.join();
}
Run Code Online (Sandbox Code Playgroud)
据我了解,我可以暂停和使用恢复该线程std::condition_variable的指出这里在我前面的问题.
但是,如果我只是使用std::atomic<bool> thread_running执行或不执行GetData()下面的逻辑,是否有缺点?
GetData() {
if (thread_running == false)
return;
//Some heavy logic
}
Run Code Online (Sandbox Code Playgroud)
与使用 …
我正在学习std::mutex,std::thread我对下面两段代码的不同行为感到惊讶:
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
std::mutex mtx;
void foo(int k)
{
std::lock_guard<std::mutex> lg{ mtx };
for (int i = 0; i < 10; ++i)
cout << "This is a test!" << i << endl;
cout << "The test " << k << " has been finished." << endl;
}
int main()
{
std::thread t1(foo, 1);
std::thread t2(foo, 2);
t1.join();
t2.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是顺序的.但如果我没有名称变量std::lock_guard<std::mutex>,则输出无序
void foo(int k)
{ …Run Code Online (Sandbox Code Playgroud) 我知道std::thread析构函数是在主出口或线程对象超出范围时调用的。
但是,当它所调用的函数完成执行时,它还会被销毁吗?
如果不是这样的线程会发生什么,我还join()可以吗?
在C++ 11上面直接存储作为类成员的优点或缺点std::thread是这样的:
std::thread my_thread;
Run Code Online (Sandbox Code Playgroud)
而不是像这样存储一个std::shared_ptr或std::unique_ptr多个线程:
std::shared_ptr<std::thread> my_thread_ptr;
Run Code Online (Sandbox Code Playgroud)
任何代码选项都比其他更好吗?或者没关系,只需要2种不同的方式来处理线程对象.
以下代码可靠地产生段错误。
#include <vector>
#include <thread>
class Class {
public:
Class(const int integer)
: cinteger(integer), carray(std::array<int, 1>{0})
{}
const int operator()()
{
carray[cinteger] = 0;
return cinteger;
}
private:
int cinteger;
std::array<int, 1> carray;
};
class Worker{
public:
Worker( Class iClass):
wClass(iClass),
thread(&Worker::thread_main, this)
{}
void join(){thread.join();}
private:
Class wClass;
std::thread thread;
void thread_main(){
for(int i = 0; i < 50000; i++)
wClass();
}
};
int main()
{
std::vector<Worker> Workers;
for(int i = 0; i < 4; i++)
Workers.emplace_back(Class(0));
for(int i …Run Code Online (Sandbox Code Playgroud)