给出如下:
void test()
{
std::chrono::seconds dura( 20 );
std::this_thread::sleep_for( dura );
}
int main()
{
std::thread th1(test);
std::chrono::seconds dura( 5 );
std::this_thread::sleep_for( dura );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
main将在5秒后退出,那还会发生什么th1?
即使th1您定义的线程对象main超出范围并被销毁,它是否会继续执行直到完成?
th1完成执行后是否只是坐在那里或在程序终止时以某种方式清理?
如果线程是在函数中创建的,那么main- 在程序终止或函数超出范围之前,线程是否保持不变?
join如果你想在线程上有某种类型的超时行为,那么简单地不调用线程是否安全?
我有一个使用std :: thread将数据传递到线程的问题.我以为我理解了复制构造函数等的一般语义,但似乎我并没有完全理解这个问题.我有一个名为Log的简单类,它隐藏了它的复制构造函数:
class Log
{
public:
Log(const char filename[], const bool outputToConsole = false);
virtual ~Log(void);
//modify behavior
void appendStream(std::ostream *);
//commit a new message
void commitStatus(const std::string str);
private:
//members
std::ofstream fileStream;
std::list<std::ostream *> listOfStreams;
//disable copy constructor and assignment operator
Log(const Log &);
Log & operator=(const Log &);
}
Run Code Online (Sandbox Code Playgroud)
int main()
{
static int portNumber = 10000;
Log logger("ServerLog.txt", true);
logger.commitStatus("Log Test String");
try {
boost::asio::io_service ioService;
server(ioService, portNumber, logger);
}
catch (std::exception &e)
{ …Run Code Online (Sandbox Code Playgroud) 如果在Ubuntu 12.04上使用Clang 3.2或GCC 4.7进行编译,则以下示例成功运行(即不挂起),但如果我使用VS11 Beta或VS2012 RC进行编译,则会挂起.
#include <iostream>
#include <string>
#include <thread>
#include "boost/thread/thread.hpp"
void SleepFor(int ms) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
template<typename T>
class ThreadTest {
public:
ThreadTest() : thread_([] { SleepFor(10); }) {}
~ThreadTest() {
std::cout << "About to join\t" << id() << '\n';
thread_.join();
std::cout << "Joined\t\t" << id() << '\n';
}
private:
std::string id() const { return typeid(decltype(thread_)).name(); }
T thread_;
};
int main() {
static ThreadTest<std::thread> std_test;
static ThreadTest<boost::thread> boost_test;
// SleepFor(100);
}
Run Code Online (Sandbox Code Playgroud)
问题似乎是,std::thread::join()如果在main …
我试图从我的类中生成一个线程,并且该线程在我的类中执行一个特定的方法.代码如下所示:
class ThreadClass{
int myThread(int arg){
// do something
}
void createThread(){
thread t = thread(myThread,10);
}
} ;
Run Code Online (Sandbox Code Playgroud)
编译时的这段代码会引发错误说法
std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = int (ThreadClass::*)(int), _Args = {int}]
no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘int (ThreadClass::*&&)(int)’
Run Code Online (Sandbox Code Playgroud)
我不确定这里的实际错误是什么.有人可以帮我弄这个吗?
谢谢.
我正在尝试建立一些启发式方法来帮助我确定std::thread要使用的适当类.
据我了解,从最高级别(最简单到使用,但最不灵活)到最低级别,我们有:
我想我对何时使用前两个有一个很好的把握,但我仍然不清楚std::promise.
std::future与std::async调用一起,有效地将生成的回调/函数/ lambda转换为异步调用(根据定义,它立即返回).一个单一的消费者可以拨打std::future::get()阻止电话,以获得结果.
std::shared_future 只是一个允许多个消费者的版本.
如果要将std::future值与生成器回调绑定,但希望将实际调用推迟到以后(将任务关联到生成线程时),std::packaged_task则是正确的选择.但是现在,由于对应std::future于std::package_taskcan,在一般情况下,可以由多线程访问,我们可能必须小心使用a std::mutex.请注意std::async,在第一种情况下,我们不必担心锁定.
阅读了一些关于承诺的有趣链接,我想我理解它的机制以及如何设置它们,但我的问题是,你什么时候会选择使用其他三个承诺呢?
我正在寻找一个应用程序级别的答案,比如一个经验法则(填写上面的???),而不是链接中的答案(例如使用std :: promise来实现一些库机制),所以我可以更容易地解释如何为初级用户选择合适的类std::thread.
换句话说,这将是很好有什么我可以用做一个有用的例子std::promise是不能与其他机制来完成.
回答
A std::future是一种奇怪的野兽:一般来说,你不能直接修改它的值.
可以修改其价值的三个生产者是:
std::async通过异步回调,它将返回一个std::future实例.std::packaged_task,当传递给线程时,将调用其回调,从而更新std::future与之关联的实例std::packaged_task.此机制允许生成器的早期绑定,但稍后调用.std::promise,允许std::future通过其 …我的目标是将std::thread对象保留为数据成员,并在需要时对其进行初始化.
我无法执行此操作(如下面的代码中所示),因为类的复制构造函数std::thread已被删除.还有其他办法吗?
class MyClass
{
public:
MyClass():DiskJobThread(){};
~MyClass();
void DoDiskJobThread();
private:
int CopyThread(const std::wstring & Source, const std::wstring & Target);
int MoveThread(const std::wstring & Source, const std::wstring & Target);
std::thread DiskJobThread;
};
MyClass::~MyClass()
{
DiskJobThread.join();
}
void MyClass::DoDiskJobThread()
{
std::wstring Source = GetSource();
std::wstring Target = GetTarget();
int m_OperationType = GetOperationType();
if (m_OperationType == OPERATION_COPY)
{
DiskJobThread = std::thread(&MyClass::CopyThread, *this, Source, Target);
}
else if (m_OperationType == OPERATION_MOVE)
{
DiskJobThread = std::thread(&MyClass::MoveThread, *this, Source, Target);
} …Run Code Online (Sandbox Code Playgroud) 我想在向量中存储一组线程,并在退出程序之前将它们全部加入.尝试加入第一个线程时,无论我在集合中放置了多少,我都会收到以下错误:
system_error: thread::join failed: No such process
Run Code Online (Sandbox Code Playgroud)
这是一些演示我的问题的简单代码:
#include <thread>
#include <iostream>
#include <vector>
#include <functional>
using std::cout;
using std::endl;
using std::vector;
using std::thread;
using std::mem_fn;
int main()
{
vector<thread> threads(1);
threads.push_back(thread([]{ cout << "Hello" << endl; }));
for_each(threads.begin(), threads.end(), mem_fn(&thread::join));
// also tried --> for(thread &t : threads) t.join()
}
Run Code Online (Sandbox Code Playgroud)
我正在使用以下内容构建它(尝试过clang ++ 4.2.1和g ++ 5.3.1):
g++ -o src/thread_test.o -c -std=c++14 src/thread_test.cpp -pthread
g++ -o thread_test src/thread_test.o -pthread
Run Code Online (Sandbox Code Playgroud)
我在互联网上看到很多这样的例子.合同中的某些内容是否发生了变化,<thread>或者<vector>说这些例子已经解散了?
注意:作为未来读者的一小部分,我在尝试{}赋值后最终添加了(1)构造函数参数,由于私有拷贝构造函数而失败.在试图避免复制构造函数时,我最终分配了未初始化的线程 - 粗心的错误.
我想检查一下是否std::thread已完成执行.搜索stackoverflow我发现以下问题解决了这个问题.接受的答案建议让工作线程在退出之前设置变量并让主线程检查该变量.以下是此类解决方案的最小工作示例:
#include <unistd.h>
#include <thread>
void work( bool* signal_finished ) {
sleep( 5 );
*signal_finished = true;
}
int main()
{
bool thread_finished = false;
std::thread worker(work, &thread_finished);
while ( !thread_finished ) {
// do some own work until the thread has finished ...
}
worker.join();
}
Run Code Online (Sandbox Code Playgroud)
对已接受的答案发表评论的人声称,不能使用简单的bool变量作为信号,代码在没有内存屏障的情况下被破坏并且使用std::atomic<bool>是正确的.我最初的猜测是这是错误的,简单bool就足够了,但我想确保我没有错过任何东西.以上代码是否需要a std::atomic<bool>才能正确?
假设主线程和worker正在不同套接字中的不同CPU上运行.我认为会发生的是,主线程thread_finished从其CPU的缓存中读取.当worker更新它时,缓存一致性协议负责将worker更改为全局内存并使主线程的CPU缓存无效,因此它必须从全局内存中读取更新的值.缓存一致性的全部要点是不能像上面的代码一样工作吗?
在 lambda 中捕获 thread_local:
#include <iostream>
#include <thread>
#include <string>
struct Person
{
std::string name;
};
int main()
{
thread_local Person user{"mike"};
Person& referenceToUser = user;
// Works fine - Prints "Hello mike"
std::thread([&]() {std::cout << "Hello " << referenceToUser.name << std::endl;}).join();
// Doesn't work - Prints "Hello"
std::thread([&]() {std::cout << "Hello " << user.name << std::endl;}).join();
// Works fine - Prints "Hello mike"
std::thread([&user=user]() {std::cout << "Hello " << user.name << std::endl;}).join();
}
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/zeocG5ohb
看起来如果我使用 a 的原始名称,thread_local那么执行 …