【发布时间】:2021-06-05 11:06:39
【问题描述】:
我正面临一个非常奇怪的问题。我的源目录包含以下内容:
❯ tree .
├── CMakeLists.txt
├── main.cpp
└── stoppable_task.hpp
0 directories, 3 files
stoppable_task.hpp的内容在哪里:
#ifndef STOPPABLE_TASK_HPP
#define STOPPABLE_TASK_HPP
#include <future>
enum class TaskState : unsigned char {
Ready = 0,
Executing = 1,
Terminating = 2
};
class StoppableTask {
std::promise<void> exit_signal;
std::future<void> future_obj;
protected:
TaskState task_state;
virtual void run() = 0;
public:
StoppableTask()
: future_obj(exit_signal.get_future()),
task_state(TaskState::Ready) {}
StoppableTask(const StoppableTask&) = delete;
StoppableTask& operator=(const StoppableTask&) = delete;
virtual void operator()() {
task_state = TaskState::Executing;
run();
}
bool is_stop_requested(int timeout_in_ms = 100) const {
std::chrono::milliseconds t(timeout_in_ms);
return (future_obj.wait_for(t) == std::future_status::ready);
}
void request_stop() {
task_state = TaskState::Terminating;
exit_signal.set_value();
}
TaskState get_task_state() {
return task_state;
}
};
#endif
main.cpp的内容是:
#include "stoppable_task.hpp"
#include <iostream>
#include <memory>
class Speak : public StoppableTask {
int count;
public:
Speak() : count(0), StoppableTask() {}
Speak(const Speak&) = delete;
Speak& operator=(const Speak&) = delete;
void run() override {
std::cout << ++count << " -- speaking ... " << std::endl;
}
};
int main() {
int i = 10;
std::unique_ptr<Speak> spk = std::make_unique<Speak>();
do {
(*spk)();
if (--i <= 0) {
spk->request_stop();
}
} while(not spk->is_stop_requested());
return 0;
}
我正在使用以下CMakeLists.txt文件进行编译。
cmake_minimum_required(VERSION 3.16)
project(stoppable_task)
set(CMAKE_CXX_STANDARD 17)
find_package(Threads REQUIRED)
set(SRC_FILES
main.cpp
)
set(HDR_FILES
stoppable_task.hpp
)
add_executable(stoppable_task ${SRC_FILES} ${HDR_FILES})
target_link_libraries(stoppable_task Threads::Threads)
在通过 CMake 编译时,程序抛出 SIGABRT 错误,如下所示:
❯ ./stoppable_task
1 -- speaking ...
2 -- speaking ...
3 -- speaking ...
4 -- speaking ...
5 -- speaking ...
6 -- speaking ...
7 -- speaking ...
8 -- speaking ...
9 -- speaking ...
10 -- speaking ...
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
fish: “./stoppable_task” terminated by signal SIGABRT (Abort)
this page 的解决方案说手动编译如下:
❯ g++ -std=c++17 main.cpp -pthread
令人惊讶的是,手动编译可以正常工作并且没有引发错误。谁能解释第一个 CMake 方法有什么问题,我该如何解决?提前致谢。
【问题讨论】:
-
能否请您提供使用
VERBOSE=1 make的CMake 构建的输出? -
另一个提示以匹配您的命令行行为以添加以下选项以及 c++17 标准
set(CMAKE_CXX_STANDARD_REQUIRED ON)和set(CMAKE_CXX_EXTENSIONS OFF) -
可能重复,见stackoverflow.com/a/39547577/775806(接受的答案是错误的)。