C++ C+的Pthread+;类函数,该函数使用引用来类对象

C++ C+的Pthread+;类函数,该函数使用引用来类对象,c++,multithreading,reference,pthreads,C++,Multithreading,Reference,Pthreads,我有这样的要求:- 1) 有两个类,比如Wrapper和Wrapper2。 2) Wrapper2包含类Wrapper的引用对象。 3) 线程将数据写入类包装器的变量,该变量本质上应该调用包装器的成员函数。 4) 另一个线程可以读写数据到包装器的类成员,这个线程基本上可以通过包装器2调用 根据关于Stackoverflow的老问题的一些答案,我创建了一个示例代码来检查为什么我的生产代码失败,我无法找出问题所在。一旦创建thread2,它就会接收SIGSEG信号。代码如下:- #inclu

我有这样的要求:- 1) 有两个类,比如Wrapper和Wrapper2。 2) Wrapper2包含类Wrapper的引用对象。 3) 线程将数据写入类包装器的变量,该变量本质上应该调用包装器的成员函数。 4) 另一个线程可以读写数据到包装器的类成员,这个线程基本上可以通过包装器2调用

根据关于Stackoverflow的老问题的一些答案,我创建了一个示例代码来检查为什么我的生产代码失败,我无法找出问题所在。一旦创建thread2,它就会接收SIGSEG信号。代码如下:-

    #include <thread>
    #include <iostream>
    #include <chrono>
    #include <unistd.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <stdio.h>
    #include <signal.h>
    #include <pthread.h>
    #include <wait.h>
    #include <string.h>

    pthread_mutex_t mt1;

    void thread_signal(int signum)
    {
      pthread_exit(0);
    }

    void sig_func(int sig)
    {
     write(1, "Caught signal 11\n", 17);
     std::cout<<"Caught signal :"<<sig<<std::endl;
     signal(SIGSEGV,sig_func);
     thread_signal(sig);
    }

    class Wrapper {
       public:
        Wrapper():i(10)
       {
            std::cout<<"Wrapper Constructor Called. "<<this<<" \n";
       }
        ~Wrapper()
       {
            std::cout<<"Wrapper Destructor Called. "<<this<<"\n";
       }
          void member1() {
              std::cout << "i am member1" << std::endl;
          }
          void member2(const char *arg1, unsigned arg2) {
              std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
          }
        void setI(int i)
        {
            pthread_mutex_lock(&mt1);
            this->i=i;
            std::cout<<"set: "<< this->i<<std::endl;
            pthread_mutex_unlock(&mt1);
        }
        int getI()
        {
            pthread_mutex_lock(&mt1);
            std::cout<<"get: "<< this->i<<std::endl;
            pthread_mutex_unlock(&mt1);
            return 0;
        }
        int i;
    };

    class Wrapper2
    {
    public:
        Wrapper2(Wrapper & wp):wp2(wp)
    {
            std::cout<<"Wrapper2 Constructor Called. "<<this<<" \n";
    }

        ~Wrapper2()
       {
            std::cout<<"Wrapper2 Destructor Called. "<<this<<" \n";
       }
        Wrapper & wp2;
    };


    struct ThreadWrapper {
        Wrapper & wr1;
        Wrapper2 & wr2;

        ThreadWrapper( Wrapper & wr1,Wrapper2& wr2):
                    wr1(wr1),wr2(wr2)
        {

        }

    };

    extern "C" void* wrapper1Fun ( void* wr1)
    {
        std::auto_ptr< Wrapper > wrp1 ( static_cast< Wrapper* >( wr1 ) );
        std::cout<<"Thread 1 created. \n";
        while(1)
        {
            wrp1->setI(rand()%100);
            usleep(50);
        }

        return 0;
    }

    extern "C" void* wrapper2Fun ( void* wr2)
    {
        std::auto_ptr< Wrapper2 > wrp2 ( static_cast< Wrapper2* >( wr2 ) );
        std::cout<<"Thread 2 created. \n";
        while(1)
        {
            wrp2->wp2.getI();
            usleep(50);
        }

        return 0;
    }

    int main(int argc, char **argv) {
      struct sigaction sa;
      memset(&sa, 0, sizeof(sa));
      sa.sa_handler = thread_signal;
      sa.sa_flags = 0;
      sigaction(SIGTERM, &sa, 0);
      bool mainRunning= true;
       Wrapper w;
       Wrapper2 w1(w);

       sleep(1);
       ThreadWrapper * myWrap = new ThreadWrapper(w,w1);
       sleep(1);
       pthread_t pt1;
       pthread_t pt2;
       pthread_attr_t attr;
       signal(SIGSEGV,sig_func); // Register signal handler before going multithread
       pthread_attr_init(&attr);
       int i = pthread_create(&pt1, NULL,wrapper1Fun, myWrap);
       std::cout<<"First thread status "<<i<<std::endl;
       sleep(1);
       int j = pthread_create(&pt2, &attr,wrapper2Fun, myWrap);
       std::cout<<"Second thread status "<<j<<std::endl;
       sleep(1);
       while(1);
       fprintf(stderr, "kill thread\n");
       //pthread_kill(pt1, SIGTERM);
       fprintf(stderr, "join thread\n");
       pthread_join(pt1, NULL);
       pthread_join(pt1, NULL);

       return 0;
    }
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
pthread_mutex_t mt1;
无效螺纹信号(内部信号)
{
pthread_退出(0);
}
无效信号函数(内部信号)
{
写入(1,“捕获信号11\n”,17);

std::cout
wrapper1Fun
希望传递一个指向
Wrapper
的指针,
wrapper2Fun
希望传递一个指向
wrapper2
的指针。但实际上,您正在向每个线程传递一个指向
ThreadWrapper
的指针,这是一种完全不同的类型,所以它出错了

<> >使用<代码> Value*/Cux>和强制转换,防止编译器指出您的类型错误。我建议使用类型安全的C++线程库,而不是原始代码> pthOx/Coo>。Boost有一个,与C++ 11标准库一样。 此外,您使用的
auto\u ptr
最多也值得怀疑。它已被弃用,很容易出错,而且表达所有权的方式也很差-首选
unique\u ptr
shared\u ptr

这里您构造了两个拥有相同指针的
auto_ptr
值,因此它将被释放两次,这是未定义的行为


在任何情况下,都没有明显的理由将这些对象放在堆上。如果这样做,则需要确定内存的所有权所在。

wrapper1Fun
希望传递一个指向
包装器的指针,而
wrapper2Fun
希望传递一个指向
包装器2
的指针。但实际上,您是y将指向
ThreadWrapper
的指针传递给每个线程,这是一种完全不同的类型,因此出错

<> >使用<代码> Value*/Cux>和强制转换,防止编译器指出您的类型错误。我建议使用类型安全的C++线程库,而不是原始代码> pthOx/Coo>。Boost有一个,与C++ 11标准库一样。 此外,您使用的
auto\u ptr
最多也值得怀疑。它已被弃用,很容易出错,而且表达所有权的方式也很差-首选
unique\u ptr
shared\u ptr

这里您构造了两个拥有相同指针的
auto_ptr
值,因此它将被释放两次,这是未定义的行为


在任何情况下,都没有明显的理由将这些对象放在堆上。如果这样做,则需要确定内存的所有权所在。

wrapper1Fun
希望传递一个指向
包装器的指针,而
wrapper2Fun
希望传递一个指向
包装器2
的指针。但实际上,您是y将指向
ThreadWrapper
的指针传递给每个线程,这是一种完全不同的类型,因此出错

<> >使用<代码> Value*/Cux>和强制转换,防止编译器指出您的类型错误。我建议使用类型安全的C++线程库,而不是原始代码> pthOx/Coo>。Boost有一个,与C++ 11标准库一样。 此外,您使用的
auto\u ptr
最多也值得怀疑。它已被弃用,很容易出错,而且表达所有权的方式也很差-首选
unique\u ptr
shared\u ptr

这里您构造了两个拥有相同指针的
auto_ptr
值,因此它将被释放两次,这是未定义的行为


在任何情况下,都没有明显的理由将这些对象放在堆上。如果这样做,则需要确定内存的所有权所在。

wrapper1Fun
希望传递一个指向
包装器的指针,而
wrapper2Fun
希望传递一个指向
包装器2
的指针。但实际上,您是y将指向
ThreadWrapper
的指针传递给每个线程,这是一种完全不同的类型,因此出错

<> >使用<代码> Value*/Cux>和强制转换,防止编译器指出您的类型错误。我建议使用类型安全的C++线程库,而不是原始代码> pthOx/Coo>。Boost有一个,与C++ 11标准库一样。 此外,您使用的
auto\u ptr
最多也值得怀疑。它已被弃用,很容易出错,而且表达所有权的方式也很差-首选
unique\u ptr
shared\u ptr

这里您构造了两个拥有相同指针的
auto_ptr
值,因此它将被释放两次,这是未定义的行为


在任何情况下,都没有明显的理由将这些对象放在堆上。如果你这样做,你需要决定内存的所有权在哪里。

是什么让你认为你需要使用
std::auto_ptr
?包装周围的包装。非常复杂。是什么让你认为你需要使用
std::auto_ptr
?包装周围的w说唱歌手。非常复杂。什么让你认为你需要使用
std::auto_ptr
?包装周围的包装。非常复杂。什么让你认为你需要使用
std::auto_ptr
?包装周围的包装。非常复杂。谢谢@Alan,你救了我一天和几个小时的挫败感。我只是没能弄明白。我想要我被要求使用c++11线程,我也这么做了,然后这里的人只需要pthread,然后我需要