假设我正在启动a std::thread
然后detach()
它,所以线程继续执行,即使std::thread
它曾经表示它,超出范围.
进一步假设该程序不具有用于接合分离的线程一个可靠的协议1,所以分离线程仍然运行时main()
退出.
我在标准中找不到任何东西(更准确地说,在N3797 C++ 14草案中),它描述了应该发生的事情,1.10和30.3都没有包含相关的措辞.
1另一个可能是等同的问题是:"可以再次连接一个分离的线程",因为你要发明加入的协议,信号部分必须在线程仍在运行时完成,并且OS调度程序可能决定在执行信令之后让线程休眠一小时,接收端无法可靠地检测到线程实际完成.
如果用完main()
了卸下运行的线程是不确定的行为,那么任何使用的std::thread::detach()
是除非主线程永远不会退出未定义行为2.
因此,运行main()
脱离线程的耗尽必须具有已定义的效果.问题是:其中(在C++标准,不POSIX,不OS文档,......)都处于所定义的那些的效果.
2分离的线程不能加入(在感std::thread::join()
).您可以等待分离线程的结果(例如,通过未来std::packaged_task
,或通过计数信号量或标志和条件变量),但这并不能保证线程已完成执行.事实上,除非你把信令部分进入线程的第一个自动对象的析构函数,也将在一般情况下,是运行的代码(析构函数)后的信号代码.如果操作系统安排主线程使用结果并在分离的线程完成运行所述析构函数之前退出,^ Wis定义会发生什么?
我通过线程获得C++错误:
terminate called without an active exception
Aborted
Run Code Online (Sandbox Code Playgroud)
这是代码:
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
template<typename TYPE>
class blocking_stream
{
public:
blocking_stream(size_t max_buffer_size_)
: max_buffer_size(max_buffer_size_)
{
}
//PUSH data into the buffer
blocking_stream &operator<<(TYPE &other)
{
std::unique_lock<std::mutex> mtx_lock(mtx);
while(buffer.size()>=max_buffer_size)
stop_if_full.wait(mtx_lock);
buffer.push(std::move(other));
mtx_lock.unlock();
stop_if_empty.notify_one();
return *this;
}
//POP data out of the buffer
blocking_stream &operator>>(TYPE &other)
{
std::unique_lock<std::mutex> mtx_lock(mtx);
while(buffer.empty())
stop_if_empty.wait(mtx_lock);
other.swap(buffer.front());
buffer.pop();
mtx_lock.unlock();
stop_if_full.notify_one();
return *this;
}
private:
size_t max_buffer_size;
std::queue<TYPE> buffer;
std::mutex mtx;
std::condition_variable stop_if_empty,
stop_if_full;
bool …
Run Code Online (Sandbox Code Playgroud) 我一直在使用该pthread
库来创建和连接C中的线程.
我应该何时从一开始就创建一个脱离的线程?与可连接线程相比,它是否提供任何性能优势?
pthread_join()
在连接(默认情况下)线程上不执行操作是否合法?或者这样的线程是否应该始终使用该detach()
功能pthread_exit()
?
我不明白为什么当std::thread
销毁销毁时它必须处于join()或detach()状态。
联接等待线程完成,而分离则没有。似乎有些中间状态我不了解。因为我的理解是join和detach是互补的:如果不调用join(),则默认为detach()。
这样说,假设您正在编写一个创建线程的程序,并且仅在此线程的生命周期后期才调用join(),所以直到您调用join为止,该线程基本上像分离的线程一样在运行,没有?
从逻辑上讲,detach()应该是线程的默认行为,因为这是线程的定义,它们与其他线程无关地并行执行。
那么,当线程对象被破坏时,为什么要调用Terminate()?为什么标准不能简单地将线程视为已分离?
我不了解在销毁线程之前未调用join()或detached()时终止程序的原因。这样做的目的是什么?
更新:
我最近遇到了这个。安东尼·威廉姆斯(Anthony Williams)在他的《并发中的行动》一书中指出:“ C ++ 17的建议之一是为join_thread类提供类似于std :: thread的要求,只是它会像scoped_thread一样自动加入析构函数中。这在委员会中没有达成共识,因此未被标准接受(尽管对于C ++ 20来说,它仍然可以按std :: jthread的标准进行...)”
我已经整理了一个简单的c ++计时器类,它应该定期从SO上的各种示例调用给定的函数,如下所示:
#include <functional>
#include <chrono>
#include <future>
#include <cstdio>
class CallBackTimer
{
public:
CallBackTimer()
:_execute(false)
{}
void start(int interval, std::function<void(void)> func)
{
_execute = true;
std::thread([&]()
{
while (_execute) {
func();
std::this_thread::sleep_for(
std::chrono::milliseconds(interval));
}
}).detach();
}
void stop()
{
_execute = false;
}
private:
bool _execute;
};
Run Code Online (Sandbox Code Playgroud)
现在我想从C++类中调用它,如下所示
class Processor()
{
void init()
{
timer.start(25, std::bind(&Processor::process, this));
}
void process()
{
std::cout << "Called" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
但是,这会调用错误
terminate called after throwing an instance of 'std::bad_function_call'
what(): bad_function_call
Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,它使用线程中的getline()从标准输入读取数据.我想从主线程关闭应用程序,而getline仍然阻止其他线程.怎么能实现这一目标?
我不想强迫用户必须按ctrl-Z来关闭stdin和应用程序.
到目前为止,我已尝试使用Windows 8.1 64bit,v120平台工具集上的编译器设置(RuntimeLibrary =/MT):
*更新*
*更新2:解决方案*
显示问题的示例代码:
#include <iostream>
#include <thread>
#include <string>
#include <chrono>
int main(int argc, char *argv[])
{
bool stop = false;
std::thread *t = new std::thread([&]{
std::string line;
while (!stop && std::getline(std::cin, line, '\n')) {
std::cout << line;
}
});
std::this_thread::sleep_for(std::chrono::seconds(1));
stop = true;
// how to stop thread or make getline to return here?
return 0; …
Run Code Online (Sandbox Code Playgroud) 我正在尝试实现从C#Unity到C++的异步接口.
这是C++中的公开函数:
struct Vector3 {
float x;
float y;
float z;
};
extern "C" {
DLLEXPORT void sync_test(void*(Vector3[], int));
DLLEXPORT void async_test(void*(Vector3[], int));
}
Run Code Online (Sandbox Code Playgroud)
它们是这样实现的:
void do_work(void*(onResult)(Vector3[], int)) {
int size = 30;
Vector3* result = new Vector3[size];
for (int i = 0; i < size; i++) {
result[i] = { 5,(float)i,2 };
}
onResult(result, size);
delete[] result;
}
DLLEXPORT void sync_test(void*(onResult)(Vector3[], int)) {
do_work(onResult);
}
DLLEXPORT void async_test(void*(onResult)(Vector3[], int)) {
std::thread thread(do_work, onResult);
}
Run Code Online (Sandbox Code Playgroud)
这是我在C#中使用它们的方式:
[DllImport("Isosurfaces.dll")]
static extern void …
Run Code Online (Sandbox Code Playgroud) 请帮我解决一个关于以下代码输出的简单问题。
我认为只有在调用 join() 或 detach() 函数时才会执行线程。
因此,我希望输出仅打印“暂停 2 秒结束,ID = 59306 ”,而不是打印“暂停 1 秒结束,ID = 10218 ”,因为我认为只有线程 2会被执行,而线程 1会被执行。不会被执行。但是我错了。
实际上,输出实际上打印了上述两行,这意味着线程 1 和 2 都被执行。是真的吗?
您能向我解释一下代码如何实际执行两个线程吗?
=========================
#include <iostream> // std::cout
#include <thread> // std::thread, std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
void pause_thread(int n)
{
std::this_thread::sleep_for (std::chrono::seconds(n));
std::cout << "pause of " << n << " seconds ended , ID = " << std::this_thread::get_id() << std::endl;
}
int main()
{
std::cout << "Spawning 2 …
Run Code Online (Sandbox Code Playgroud)