小编kri*_*pet的帖子

关于std :: async使用std :: launch :: async参数启动的线程的混淆

我对这个std::async功能有点困惑.

规范说:正在执行的异步操作"好像在新的执行线程中"(C++11§30.6.8/ 11).

现在,这意味着什么?

在我的理解中,代码

std::future<double> fut = std::async(std::launch::async, pow2, num);
Run Code Online (Sandbox Code Playgroud)

应该pow2在新线程上启动函数并将值传递num给线程的值,然后在将来某个时候,当函数完成时,将结果放入fut(只要函数pow2具有类似的签名double pow2(double);).但规范说"似乎",这使得整个事情对我来说有点模糊.

问题是:

在这种情况下是否始终启动新线程?希望如此.我的意思是对我来说,参数std::launch::async是有意义的,我明确说明我确实想要创建一个新线程.

和代码

std::future<double> fut = std::async(std::launch::deferred, pow2, num);
Run Code Online (Sandbox Code Playgroud)

应该通过将函数调用延迟到我写的类似的点来使延迟评估成为可能.在这种情况下,参数,应该意味着我明确说明,我不想要一个新线程,我只是想确保在需要它的返回值时调用该函数.pow2var = fut.get();std::launch::deferred

我的假设是否正确?如果没有,请解释.

另外,我知道默认情况下该函数调用如下:

std::future<double> fut = std::async(std::launch::deferred | std::launch::async, pow2, num);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我被告知是否将启动新线程取决于实现.那又是什么意思呢?

c++ multithreading future c++11 stdthread

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

为什么堆上的分配比堆栈上的分配更快?

就我对资源管理的了解而言,在堆上分配一些东西(操作符new)应该总是比在堆栈上分配(自动存储)慢,因为堆栈是基于LIFO的结构,因此它需要最少的簿记,并且要分配的下一个地址的指针是微不足道的.

到现在为止还挺好.现在看下面的代码:

/* ...includes... */

using std::cout;
using std::cin;
using std::endl;

int bar() { return 42; }

int main()
{
    auto s1 = std::chrono::steady_clock::now();
    std::packaged_task<int()> pt1(bar);
    auto e1 = std::chrono::steady_clock::now();

    auto s2 = std::chrono::steady_clock::now();
    auto sh_ptr1 = std::make_shared<std::packaged_task<int()> >(bar);
    auto e2 = std::chrono::steady_clock::now();

    auto first = std::chrono::duration_cast<std::chrono::nanoseconds>(e1-s1);
    auto second = std::chrono::duration_cast<std::chrono::nanoseconds>(e2-s2);

    cout << "Regular: " << first.count() << endl
         << "Make shared: " << second.count() << endl;

    pt1();
    (*sh_ptr1)();

    cout << "As you can see, both are working …
Run Code Online (Sandbox Code Playgroud)

c++ heap stack new-operator automatic-storage

19
推荐指数
3
解决办法
1589
查看次数

与简单的分离线程相比,为什么std :: async会变慢?

我已经多次被告知,我应该使用参数std::async来解决火灾和遗忘类型的任务std::launch::async(所以它最好在新的执行线程上使用它).

在这些陈述的鼓励下,我想看看如何std::async比较:

  • 顺序执行
  • 一个简单的分离 std::thread
  • 我简单的异步"实现"

我天真的异步实现看起来像这样:

template <typename F, typename... Args>
auto myAsync(F&& f, Args&&... args) -> std::future<decltype(f(args...))>
{
    std::packaged_task<decltype(f(args...))()> task(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
    auto future = task.get_future();

    std::thread thread(std::move(task));
    thread.detach();

    return future;
}
Run Code Online (Sandbox Code Playgroud)

没有看中这里,包函子fstd::packaged task与它的参数一起,启动它的一个新的std::thread被分离,并用返回std::future的任务.

现在代码测量执行时间std::chrono::high_resolution_clock:

int main(void)
{
    constexpr unsigned short TIMES = 1000;

    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < TIMES; ++i)
    {
        someTask();
    }
    auto dur = …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading asynchronous c++11 stdasync

18
推荐指数
2
解决办法
2531
查看次数

为什么在使用LLVM时对std :: ifstream的缓冲会“破坏” std :: getline?

我有一个简单的C ++应用程序,应该从名为POSIX的管道读取行:

#include<iostream>
#include<string>
#include<fstream>

int main() {
    std::ifstream pipe;
    pipe.open("in");

    std::string line;
    while (true) {
        std::getline(pipe, line);
        if (pipe.eof()) {
            break;
        }
        std::cout << line << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

脚步:

  • 我创建了一个命名管道:mkfifo in

  • 我使用编译并运行C ++代码g++ -std=c++11 test.cpp && ./a.out

  • 我将数据输入in管道:

sleep infinity > in &  # keep pipe open, avoid EOF
echo hey > in
echo cats > in
echo foo > in
kill %1                # this closes the pipe, C++ app stops on …
Run Code Online (Sandbox Code Playgroud)

c++ macos pipe clang named-pipes

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

如何在不锁定互斥锁的情况下使用std :: atomic来实现线程安全?

我知道,在某些情况下,您可以避免使用锁定互斥锁(std::mutex)std::atomic,从而提高性能.

你能说出这样的情况,并且最好显示一些关于如何做到这一点的示例代码(你如何使用std::atomic)?

此外,当我锁定互斥锁时,性能会下降,因为其他线程在互斥锁被锁定的一段时间内无法继续工作.这是互斥锁的唯一问题吗?我的意思是,锁定/解锁互斥锁是一项昂贵的操作,还是仅仅是我上面提到的?

c++ multithreading c++11 stdthread stdatomic

9
推荐指数
0
解决办法
289
查看次数

为什么在N个线程上N次独立计算不快N倍?

我有一个N核处理器(在我的情况下为4).为什么在N个线程上N完全独立的函数调用大约快N倍(当然创建线程有开销,但是进一步阅读)?

查看以下代码:

namespace ch = std::chrono;
namespace mp = boost::multiprecision;
constexpr static unsigned long long int num = 3555;

// mp_factorial uses boost/multiprecision/cpp_int, so I get legit results

    ch::steady_clock::time_point s1 = ch::steady_clock::now();
    auto fu1 = std::async(std::launch::async, mp_factorial, num);
    auto fu2 = std::async(std::launch::async, mp_factorial, num);
    auto fu3 = std::async(std::launch::async, mp_factorial, num);
    auto fu4 = std::async(std::launch::async, mp_factorial, num);
    fu1.get(); fu2.get(); fu3.get(); fu4.get();
    ch::steady_clock::time_point e1 = ch::steady_clock::now();

    ch::steady_clock::time_point s2 = ch::steady_clock::now();
    mp_factorial(num);
    mp_factorial(num);
    mp_factorial(num);
    mp_factorial(num);
    ch::steady_clock::time_point e2 = ch::steady_clock::now();

    auto t1 = ch::duration_cast<ch::microseconds>(e1 …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading multicore cpu-cores parallelism-amdahl

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

如何在Python中阻止在命名管道上阻塞的线程?

我有一个子类threading.Thread.唯一的责任是将从UNIX命名管道读取的消息放入queue.Queue对象(以便其他线程可以在以后处理这些值).

示例代码:

class PipeReaderThread(Thread):
    def __init__(self, results_queue, pipe_path):
        Thread.__init__(self)
        self._stop_event = Event()
        self._results_queue = results_queue
        self._pipe_path = pipe_path

    def run(self):
        while not self._stop_event.is_set():
            with open(self._pipe_path, 'r') as pipe:
                message = pipe.read()
            self._results_queue.put(message, block=True)

    def stop(self):
        self._stop_event.set()
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我想使用一个threading.Event对象来停止循环,但由于命名管道上的open()read()调用将阻塞(直到有人打开管道写入/写入然后关闭它),线程永远不会有机会停.

我不想对命名管道使用非阻塞模式,因为阻塞实际上是我想要的,我想等待某人打开并写入管道.

使用套接字我会尝试在套接字上设置超时标志,但我找不到任何方法为命名管道执行此操作.我还考虑过用冷血杀死线程而不给它机会优雅地停止,但这并不像我应该做的那样,我甚至不知道Python是否提供了这样做的方法.

我应该如何正确地停止这个线程,以便我可以join()在之后调用它?

multithreading pipe named-pipes blocking python-3.x

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

在C++ 11中实现一个简单的通用线程池

我想创建一个用于实验目的的线程池(以及有趣的因素).它应该能够处理各种各样的任务(所以我可以在以后的项目中使用它).


在我的线程池类中,我将需要某种任务队列.由于标准库std::packaged_task从C++ 11标准开始提供,我的队列看起来像std::deque<std::packaged_task<?()> > task_queue,所以客户端可以std::packaged_task通过某种公共接口函数将s 推入队列(然后池中的一个线程将通知一个条件变量来执行它,等等.


我的问题与std::packaged_task<?()>deque中s 的模板参数有关.

函数签名?()应该能够处理任何类型/数量的参数,因为客户端可以执行以下操作:

std::packaged_task<int()> t(std::bind(factorial, 342)); thread_pool.add_task(t);

所以我不必处理参数的类型/数量.

但是回报价值应该是多少?(因此问号)

  • 如果我将整个线程池类作为模板类,它的一个实例将只能处理具有特定签名的任务(如std::packaged_task<int()>).

    我希望一个线程池对象能够处理任何类型的任务.

  • 如果我使用std::packaged_task<void()>并且调用的函数返回一个整数,或者任何东西,那么这就是未定义的行为.

c++ multithreading packaged-task c++11 stdthread

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

如何在bash命令替换中使用`set -e`?

我有一个简单的shell脚本,其中包含以下内容:

#!/usr/bin/env bash
set -eu
set -o pipefail
Run Code Online (Sandbox Code Playgroud)

我还具有以下功能:

foo() {
  printf "Foo working... "
  echo "Failed!"
  false  # point of interest #1
  true   # point of interest #2
}
Run Code Online (Sandbox Code Playgroud)

执行foo()作为常规命令按预期工作:脚本退出时#1,由于返回码false是非零和我们使用set -e

我的目标是将函数的输出捕获到foo()变量中,并仅在执行时出现错误时打印它foo()。这是我想出的:

printf "Doing something that could fail... "
if a="$(foo 2>&1)"; then
  echo "Success!"
else
  code=$?
  echo "Error:"
  printf "${a}"
  exit $code
fi
Run Code Online (Sandbox Code Playgroud)

该脚本不会在处退出,#1并且会执行"Success!"if语句的路径。注释掉trueat将#2导致执行语句的"Error:"路径 …

bash shell subshell command-substitution

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

智能指针的效率如何?

我知道,它std::shared_ptr使用引用计数,因此它具有复制和移动语义,另一方面std::unique_ptr(因此名称唯一)只有移动语义,因此尝试复制它是一个编译错误.

然而,对我而言,它并不十分清楚.我可以简单地使用std::shared_ptrstd::unique_ptr在大多数情况下,还是应该用std::unique_ptr尽可能因为它更有效,因为它没有照顾引用计数?

另外,我知道智能指针在处理时非常有用,例如异常安全,但它们通常会取代传统的T*指针吗?尽可能使用智能指针而不是传统T*指针是一种很好的编程习惯吗?

c++ pointers std c++11

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