我正试图抓住多线程并且它到目前为止还没有工作。我正在创建一个允许与设备进行串行通信的程序,并且无需多线程即可正常工作。现在我想引入线程,一个线程连续发送数据包,一个线程接收和处理数据包,另一个线程用于GUI。
前两个线程总共需要访问四个类,但使用pthread_create()
我只能传递一个参数。然后我在堆栈溢出(pthread function from a class)上发布了一篇文章,其中杰里米弗里斯纳提出了一个非常优雅的方式。然后我认为最简单的方法是创建一个包含我的线程需要访问的所有对象的Core类以及该线程的所有函数。这里是我的类Core的示例:
/** 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
}
现在我想知道处理这种情况的正确方法是什么。而不是Core.cpp中的那个技巧,我应该创建一个结构,保存指向我需要的不同类的指针,然后将该结构传递给pthread_create()函数?一般来说,这个问题的最佳解决方案是什么?
答案 0 :(得分:3)
你遇到的问题是你的主线程在创建另一个线程的那一刻退出,此时Core对象被销毁,然后程序完全退出。当您新创建的线程尝试使用Core对象并发送数据时,会发生这种情况;你要么看到绝对没有发生任何事情(如果程序在线程执行任何操作之前退出)或崩溃(如果Core在线程尝试使用它时被销毁)。理论上你也可以看到它正常工作,但由于线程可能需要一点时间来创建数据包并发送它,这是不太可能的。
你需要使用pthread_join
在退出之前阻塞主线程,直到线程完成并退出。
无论如何,你应该使用C ++ 11的线程支持或者至少使用Boost。这可以让你摆脱指针的低级别混乱。