后续:执行一个类的成员函数

Posted

技术标签:

【中文标题】后续:执行一个类的成员函数【英文标题】:Follow-up: Executing a member function of a class 【发布时间】:2013-02-28 19:01:57 【问题描述】:

这是我之前在Executing a member function of a class 发布的问题的后续。

我正在尝试以一种方式试验 C++1.1 线程,它接受一个类的成员函数作为线程构造函数的参数,如下面第 20 行的第一个代码 sn-p 所示,标记为 .类定义在第二个代码 sn-p 中给出。根据之前相关帖子中给出的答案,代码现在可以很好地编译。但是,现在我在第一个 sn-p 的第 20 行遇到运行时错误。 GDB 回溯显示在第三个 sn-p 中。我是 C++ 新手,无法正确解释此错误。你能告诉我有什么问题吗?谢谢。

SNIPPET 1:线程初始化 (main_app.cpp)

#include <thread>
#include "ServiceRegistrar.hpp"

#define SERVER_TYPE  100065
#define SERVER_INST_LOWER  1
#define SERVER_INST_UPPER  2
#define TIMEOUT  500000

int main()

  ServiceRegistrar sr1(SERVER_TYPE, TIMEOUT, SERVER_INST_LOWER, SERVER_INST_LOWER);
      /*LINE 20 is the following*/
  std::thread t(&ServiceRegistrar::subscribe2TopologyServer, &sr1);
t.join();
  sr1.publishForSRs();


SNIPPET 2:类定义

class ServiceRegistrar

  public:
    ServiceRegistrar(int serverType, int serverTimeOut, int serverInstanceLower, int serverInstanceUpper)
       : mServerType(serverType),
         mServerTimeOut(serverTimeOut),
         mServerInstanceLower(serverInstanceLower),
         mServerInstanceUpper(serverInstanceUpper)
          

     void subscribe2TopologyServer();
     void publishForSRs();
     void publishForServices();

  private:
     int mServerType;
     int mServerTimeOut;
     int mServerInstanceLower;
         int mServerInstanceUpper;           
  ;

片段 3:GDB 回溯

  (gdb) r
  Starting program: /home/......./src/main_app 
  terminate called after throwing an instance of 'std::system_error'
  what():  Operation not permitted

  Program received signal SIGABRT, Aborted.
  0xb7fdd424 in __kernel_vsyscall ()
  (gdb) bt
  #0  0xb7fdd424 in __kernel_vsyscall ()
  #1  0xb7d471df in raise () from /lib/i386-linux-gnu/libc.so.6
  #2  0xb7d4a825 in abort () from /lib/i386-linux-gnu/libc.so.6
  #3  0xb7f2e8ad in __gnu_cxx::__verbose_terminate_handler() ()
  from /usr/lib/i386-linux-gnu/libstdc++.so.6
  #4  0xb7f2c4f3 in ?? () from /usr/lib/i386-linux-gnu/libstdc++.so.6
  #5  0xb7f2c52f in std::terminate() ()
  from /usr/lib/i386-linux-gnu/libstdc++.so.6
  #6  0xb7f2c7ce in __cxa_throw () from /usr/lib/i386-linux-gnu/libstdc++.so.6
  #7  0xb7f8772e in std::__throw_system_error(int) ()
  from /usr/lib/i386-linux-gnu/libstdc++.so.6
  #8  0xb7f8883c in   std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) () from   /usr/lib/i386-linux-gnu/libstdc++.so.6
  #9  0x0804981a in std::thread::thread<void (ServiceRegistrar::*)(),     ServiceRegistrar*>(void (ServiceRegistrar::*&&)(), ServiceRegistrar*&&) (this=0xbffff050, 
  __f=
  @0xbffff058: (void (ServiceRegistrar::*)(ServiceRegistrar * const)) 0x80491d2   <ServiceRegistrar::subscribe2TopologyServer()>)
   at /usr/include/c++/4.7/thread:133
  #10 0x08049526 in main () at main_app.cpp:20

【问题讨论】:

您可以将线程的创建包装在try 块中,并为system_error 异常添加catch 块。然后你可以在那个异常上调用what(),看看你是否得到了一些有用的信息。 不就是如图所示的“Operation not allowed”吗? @StephenLin:你是对的。我不知道为什么我跳过那一行 【参考方案1】:

这可能意味着您尚未启用线程支持。尝试将-pthread 添加到编译器的命令行参数(在链接步骤中)。

【讨论】:

我已经做过的其实很喜欢:g++ -g -c -Wall -std=c++11 main_app.cpp ServiceRegistrar.hpp -pthread 还有其他建议吗? @Fardaarda 抱歉,显然您在两个步骤中都需要它以防万一,因为 -pthread 可能会设置一些定义(这取决于编译器/平台) more info @Stephen Lin:我对这个编译链接有点新,我想知道我下面写的是否正确,因为我仍然得到这个操作不允许的错误。谢谢。 g++ -g -c -Wall -std=c++11 main_app.cpp ServiceRegistrar.hpp -pthread -lpthread @Fardaarda 不要使用-lpthread,如果您的编译器支持后者,只需使用-pthread...这是编译步骤命令 (-c),您何时链接创建可执行文件? (即g++ -o main_app...?)你也应该在那里添加-pthread

以上是关于后续:执行一个类的成员函数的主要内容,如果未能解决你的问题,请参考以下文章

c#-基础:类的进阶

请问含有多个对象成员的派生类的构造函数执行时不是先执行基类么?为啥这个先输出的是“正式生是”这个

将任何类的任何成员函数作为回调函数传递

静态构造函数, 静态成员初始化/调用顺序

如何在线程中调用其他类的成员函数和变量

Java和CSharp的类继承的执行过程的差异