0

我正在尝试使用多线程,但到目前为止它还没有工作。我正在创建一个允许与设备进行串行通信的程序,并且它在没有多线程的情况下运行良好。现在我想介绍线程,一个线程连续发送数据包,一个线程接收和处理数据包,另一个线程用于GUI。

前两个线程总共需要访问四个类,但使用pthread_create()I 只能传递一个参数。然后我偶然发现了一篇关于堆栈溢出(类中的 pthread 函数)的帖子,其中 Jeremy Friesner 提出了一种非常优雅的方式。然后我发现创建一个包含我的线程需要访问的所有对象以及线程的所有函数的核心类是最简单的。所以这是我的核心类的一个示例:

/** CORE.CPP **/

#include "SerialConnection.h"   // Clas for creating a serial connection using termios
#include "PacketGenerator.h"    // Allows to create packets to be transfered 
#include <pthread.h>

#define NUM_THREADS 4

class Core{
private:
  SerialConnection serial;    // One of the objects my threads need access to
  pthread_t threads[NUM_THREADS];
  pthread_t = _thread;

public:
  Core();
  ~Core();
  void launch_threads();    // Supposed to launch all threads
  static void *thread_send(void *arg);    // See the linked post above 
  void thread_send_function();    // See the linked post above
};

Core::Core(){
  // Open serial connection
  serial.open_connection();
}

Core::~Core(){
  // Close serial connection
  serial.close_connection();
}

void Core::launch_threads(){
  pthread_create(&threads[0], NULL, thread_send, this);

  cout << "CORE: Killing threads" << endl;
  pthread_exit(NULL);
}

void *Core::thread_send(void *arg){
  cout << "THREAD_SEND launched" << endl;
  ((Core *)arg)->thread_send_function(); 
  return NULL;
}

void Core::thread_send_function(){
  generator.create_hello_packet();
  generator.send_packet(serial);
  pthread_exit(NULL);
}   

现在的问题是我的串行对象因分段错误而崩溃(发生的指针Core::thread_send(void *arg)让我感到怀疑。即使它没有崩溃,即使程序执行没有任何错误,也不会通过串行连接传输数据。执行形式主要:

/** MAIN.CPP (extract) VARIANT 1 **/
int main(){
  Core core;
  core.launch_threads();    // No data is transferred
}

但是,如果我直接调用 thread_send_function(线程应该执行的那个),数据将通过串行连接完美传输:

/** MAIN.CPP (extract) VARIANT 1 **/
int main(){
  Core core;
  core.thread_send_function();    // Data transfer works
}

现在我想知道处理这种情况的正确方法是什么。我是否应该创建一个包含指向我需要的不同类的指针的结构,然后将该结构传递给 pthread_create() 函数,而不是 Core.cpp 中的那个诡计?一般来说,这个问题的最佳解决方案是什么?

4

1 回答 1

3

您遇到的问题是您的主线程在创建另一个线程时退出,此时核心对象被销毁,然后程序完全退出。当您新创建的线程尝试使用 Core 对象并发送数据时,就会发生这种情况;你要么看不到任何事情发生(如果程序在线程开始做任何事情之前退出)或崩溃(如果核心在线程试图使用它时被破坏)。从理论上讲,您也可以看到它正常工作,但是因为线程可能需要一些时间来创建数据包并发送它,所以这不太可能。

您需要pthread_join在退出之前使用阻塞主线程,直到线程完成并退出。

无论如何,您应该使用 C++11 的线程支持或至少 Boost 的。这将使您摆脱指针的低级混乱。

于 2013-09-19T16:06:14.137 回答