我已经看到

问题描述 投票:0回答:0

cmake_minimum_required(VERSION 3.14) project(myProject LANGUAGES C CXX) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 11) SET(CMAKE_INCLUDE_CURRENT_DIR ON) add_executable(myProject ${CMAKE_SOURCE_DIR}/main.cpp ) target_compile_options(myProject PRIVATE -Wall -Wextra) #target_link_libraries(myProject PUBLIC -static) # this causes "terminate called after throwing an instance of 'std::system_error'; what(): Unknown error 1992352464" target_link_libraries(myProject PUBLIC stdc++fs ) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(myProject PUBLIC Threads::Threads)

main.cpp

#include <cinttypes>
#include <cstdlib>
#include <iostream>
#include <ostream>
#include <fstream>

#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>

#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;

#define CHOSEN_CLOCK std::chrono::high_resolution_clock

// class Timer below derived from:
// https://raw.githubusercontent.com/99x/timercpp/refs/heads/master/timercpp.h
// https://www.fluentcpp.com/2018/12/28/timer-cpp/
// https://stackoverflow.com/q/21057676


class Timer {
    std::atomic<bool> active{true};
  public:
    std::chrono::time_point<CHOSEN_CLOCK> timer_entry_ts; // SO:31497531
    template<typename Function>
    void setInterval(Function function, int interval);
    void stop();
};

template<typename Function>
void Timer::setInterval(Function function, int interval) {
  active = true;
  std::thread t([=]() {
    while(active.load()) {
      timer_entry_ts = CHOSEN_CLOCK::now();
      function();
      if(!active.load()) return;
      std::this_thread::sleep_until(timer_entry_ts + std::chrono::milliseconds(interval));
    }
  });
  t.detach(); // it seems this causes "terminate called after throwing an instance of 'std::system_error' ; what():  Unknown error 1992278736"; if we do a -static linkage in build on Linux
}

void Timer::stop() {
  active = false;
}


Timer mtimer;
std::chrono::time_point<CHOSEN_CLOCK> last_entry_ts{};

void timer_function(void)
{
  long long int delta_micros = std::chrono::duration_cast<std::chrono::microseconds>(mtimer.timer_entry_ts-last_entry_ts).count();
  printf("%7.3f ms\n", delta_micros/1000.0f);
  last_entry_ts = mtimer.timer_entry_ts;
}

int main(const int argc, char** argv)
{
  (void)argc; // warning: unused parameter
  (void)argv; // warning: unused parameter
  static_cast<void>(pthread_create);
  static_cast<void>(pthread_cancel);

  #ifdef _GLIBCXX_HAS_GTHREADS
  printf("_GLIBCXX_HAS_GTHREADS is defined.\n");
  #else
  printf("_GLIBCXX_HAS_GTHREADS is NOT defined!\n");
  #endif

  last_entry_ts = CHOSEN_CLOCK::now();
  mtimer.setInterval(timer_function, 25); // repeat timer_function at 25 ms period
  std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // wait for 2 seconds
  mtimer.stop();
  printf("Thread stopped\n");

  std::exit(EXIT_SUCCESS);
}
我使用以下方式构建此代码:

mkdir build && cd build
cmake ../ -DCMAKE_BUILD_TYPE=Debug -G "Unix Makefiles"
make

...我都在建造它

Mingw64(在Windows 10下),我有

g++.exe (Rev3, Built by MSYS2 project) 14.2.0

raspberry pi 3b+上的raspbian伸展,我有

g++ (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516


如果我按发布的代码构建代码,那么我可以看到在两个平台上的螺纹

timer_function
    运行。
  • ,但是,如果该行是在
    target_link_libraries(myProject PUBLIC -static)
    中未接受的(启用),并且重建项目 - 然后它在mingw64/windows中再次起作用,但是它在raspbian上失败了:
  • CMakeLists.txt
    现在,很不幸,我会发现“未知错误1995920080”,所以我无法进一步研究它。但是,“ 0.202 ms”打印输出告诉我
  • $ ./myProject _GLIBCXX_HAS_GTHREADS is defined. 0.202 ms terminate called after throwing an instance of 'std::system_error' what(): Unknown error 1995920080 Aborted
跑了一次。我能做的最好的方法是通过

timer_function

确认
objdump -S ./myProject | less

似乎调用

t.detach();

-并且使用
_ZNSt6thread6detachEv
可以在该功能上设置一个断点,但是
gdb --args ./myProject

不允许我踏上它,甚至不在tui模式下(它说“ [没有可用的可用源)”);我只能说,一旦我在敲击该断点后按
gdb
tep,我就会得到上述错误:

s
(注意:我在这里看到
Https://github.com/gcc-mirror/gcc/blob/73987e69/libstdc%2b%2b%2b%2b--v3/include/include/cits/std_thread.hread.hpread.hpread.h#l324
可能最终是
gdb
环境)
任何想法,我如何才能在raspbian strave上获得此示例的构建?
	
您到达
(gdb) b _ZNSt6thread6detachEv Breakpoint 1 at 0x612b0 (gdb) r ... _GLIBCXX_HAS_GTHREADS is defined. [New Thread 0x76ffc2d0 (LWP 32461)] 1.260 ms Thread 1 "myProject" hit Breakpoint 1, 0x000612b0 in std::thread::detach() () (gdb) s Single stepping until exit from function _ZNSt6thread6detachEv, which has no line number information. 24859.580 ms terminate called after throwing an instance of 'std::system_error' what(): Unknown error 1996473040 Thread 1 "myProject" received signal SIGABRT, Aborted. raise (sig=<optimized out>) at ../sysdeps/unix/sysv/linux/raise.c:51 51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 raise (sig=<optimized out>) at ../sysdeps/unix/sysv/linux/raise.c:51 #1 0x000b6eb8 in abort () #2 0x00000020 in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?)
的尽头并退出程序,而无需确保实际停止背景线程。
当其他线程运行时,您不能仅仅从

detach()
退出;发出停止线程的信号已足够
,因此您需要更改

inline void thread::detach() { std::__throw_system_error(EINVAL); }代码以等待线程停止或提供其他机制(例如,通过返回_GLIBCXX_HAS_GTHREADS

对象并调用
-static

c++ linux multithreading static-linking
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.