Classes and multithreading

Classes and multithreading

In the project, a client is needed to communicate with lidar. The main function of the client is to receive the original byte stream sent by the radar and parse it into pcl::PointXYZ type three-dimensional coordinate points which can be directly processed by pcl. The specific implementation scheme is to design the client as a C + + class and start a sub thread in the class to receive and process the original data.

However, when the member function is directly used as an argument to create a thread object, it cannot be compiled. The problem is that the ordinary member function of the class cannot be used as the entry function of the thread. The final solution is as follows:

Method 1

The function to be executed by the thread is designed as a static member function of the class, so that the member function accepts the pointer of the class object as a parameter, and then calls the member function through the pointer. The example is as follows:

#include <iostream>
#include <thread>
#include <unistd.h>

class Test
{
private:
    int m_a{0};
    double m_b{0.};
    std::thread *m_thread{nullptr};
public:
    Test(int, double);
    ~Test();
    void start();
    void joinThread();
private:
    static void task(Test* tptr);
    void thread_func1();
    void thread_func2();
};

Test::Test(int n, double d)
    :m_a{n}, m_b{d}
{
    std::cout << "Test<" << m_a << ',' << m_b  << ">Created!\n";
}

Test::~Test()
{
    std::cout << "Destruct Test.\n";
    delete m_thread;
}

/* 
    Interface to start a child thread.
*/
void 
Test::start()
{
    m_thread = new std::thread(task, this);
}

/* 
    The task to be performed by a thread, in which member functions need to be called.
*/
void 
Test::task(Test* tptr)
{
    for (int i = 0; i < 10; ++i)
    {
        tptr->thread_func1();
        sleep(1);
        tptr->thread_func2();
        sleep(1);
    }
}

/* 
    Member function called by thread.
*/
void 
Test::thread_func1()
{
    std::cout << "Child: " << "m_a: " << m_a << '\n';
}

void 
Test::thread_func2()
{
    std::cout << "Child: " << "m_b: " << m_b << '\n';
}

/* 
    Add a child thread to the current thread.
*/
void 
Test::joinThread()
{
    (*m_thread).join();
}

int 
main(int argc, char* argv[])
{
    Test t{1, 1.1};
    t.start();
    std::cout << "Waiting the child thread\n";
    t.joinThread();
    std::cout << "Child thread terminate\n";
    sleep(1);
    std::cout << "Main thread terminate\n";
    
    return 0;
}

Method two

Ordinary non static member functions are still used, but they are called not by objects but by class scope resolution. Examples are as follows:

#include <iostream>
#include <thread>
#include <unistd.h>

class Test
{
private:
    int m_a{0};
    double m_b{0.};
    std::thread *m_thread{nullptr};
public:
    Test(int, double);
    ~Test();
    void start();
    void joinThread();
private:
    void task();
    void thread_func1();
    void thread_func2();
};

Test::Test(int n, double d)
    :m_a{n}, m_b{d}
{
    std::cout << "Test<" << m_a << ',' << m_b  << ">Created!\n";
}

Test::~Test()
{
    std::cout << "Destruct Test.\n";
    delete m_thread;
}

/* 
    Interface to start a child thread.
*/
void 
Test::start()
{
    m_thread = new std::thread(&Test::task, this);  // Calling normal member functions with class names
}

/* 
    The task to be executed by a thread, in which a member function (not defined as a static member function) needs to be called.
*/
void 
Test::task()
{
    for (int i = 0; i < 10; ++i)
    {
        thread_func1();
        sleep(1);
        thread_func2();
        sleep(1);
    }
}

/* 
    Member function called by thread.
*/
void 
Test::thread_func1()
{
    std::cout << "Child: " << "m_a: " << m_a << '\n';
}

void 
Test::thread_func2()
{
    std::cout << "Child: " << "m_b: " << m_b << '\n';
}

/* 
    Add a child thread to the current thread.
*/
void 
Test::joinThread()
{
    (*m_thread).join();
}

int 
main(int argc, char* argv[])
{
    Test t{1, 1.1};
    t.start();
    std::cout << "Waiting the child thread\n";
    t.joinThread();
    std::cout << "Child thread terminate\n";
    sleep(1);
    std::cout << "Main thread terminate\n";
    
    return 0;
}

The same python implementation

import threading
import time


class Test:

    def __init__(self, n, d):
        self.n = n
        self.d = d
        self.t = threading.Thread(target=self.task, args=())

    def start(self):
        self.t.start()

    def task(self):
        for i in range(10):
            self.thread_func1()
            time.sleep(1)
            self.thread_fun2()
            time.sleep(1)

    def thread_func1(self):
        print("Child: n = %d" % self.n)

    def thread_func2(self):
        print("Child: d = %f" % self.d)

    def join_thread(self):
        self.t.join()


def main():
    ts = Test(1, 1.1)
    ts.start()
    print("Waiting thr child thread.")
    ts.join_thread()
    print("Child thread terminate.")
    time.sleep(1)
    print("Main thread terminate.")


if __name__ == "__main__":
    main()

Tags: PCL Python

Posted on Fri, 18 Oct 2019 16:03:23 -0400 by Chrysanthus