相关疑难解决方法(0)

当main()退出时,分离线程会发生什么?

假设我正在启动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++ multithreading exit c++11 stdthread

142
推荐指数
5
解决办法
5万
查看次数

在没有活动异常的情况下调用C++终止

我通过线程获得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)

c++ multithreading deadlock c++11

70
推荐指数
3
解决办法
9万
查看次数

Detached vs. Joinable POSIX线程

我一直在使用该pthread库来创建和连接C中的线程.

  1. 我应该何时从一开始就创建一个脱离的线程?与可连接线程相比,它是否提供任何性能优势?

  2. pthread_join()在连接(默认情况下)线程上不执行操作是否合法?或者这样的线程是否应该始终使用该detach()功能pthread_exit()

c linux pthreads detach

55
推荐指数
2
解决办法
3万
查看次数

为什么在销毁线程之前必须先调用join()或detach()?

我不明白为什么当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++ multithreading

31
推荐指数
2
解决办法
2141
查看次数

C++ 11:定期调用C++函数

我已经整理了一个简单的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)

c++ c++11

6
推荐指数
1
解决办法
2万
查看次数

在stdin阻塞Windows时退出应用程序

我有一个应用程序,它使用线程中的getline()从标准输入读取数据.我想从主线程关闭应用程序,而getline仍然阻止其他线程.怎么能实现这一目标?

我不想强迫用户必须按ctrl-Z来关闭stdin和应用程序.

到目前为止,我已尝试使用Windows 8.1 64bit,v120平台工具集上的编译器设置(RuntimeLibrary =/MT):

  • freopen stdin,但它被内部锁定阻止
  • 破坏线程,调用abort()
  • 将一个Eof,行结尾放到std :: cin,它也被阻止了

*更新*

  • detach()不起作用,exit()被锁定阻止
  • winapi TerminatThread()调用abort()
  • winapi CloseHandle(GetStdHandle(STD_INPUT_HANDLE))挂起
  • 调用TerminateProcess() - 有效,但我想优雅地退出

*更新2:解决方案*

  • WriteConsoleInput()可以使std :: getline()从阻塞读取返回.这适用于任何msvc运行时库.对于工作解决方案的代码,请参见已接受

显示问题的示例代码:

#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)

windows multithreading stdin c++11 msvc12

5
推荐指数
1
解决办法
759
查看次数

托管异步接口 - >非托管代码

我正在尝试实现从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)

c++ multithreading asynchronous unity-game-engine dllexport

3
推荐指数
1
解决办法
74
查看次数

C++:不调用main函数中的join()函数,可以执行线程吗?

请帮我解决一个关于以下代码输出的简单问题。

我认为只有在调用 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)

c++ multithreading

1
推荐指数
1
解决办法
1043
查看次数