gpt4 book ai didi

c++ - 用于使用类对象引用的 C++ 类函数的 Pthread

转载 作者:行者123 更新时间:2023-11-28 00:11:58 26 4
gpt4 key购买 nike

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

基于对 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;
}

最佳答案

wrapper1Fun 期望传递一个指向 Wrapper 的指针,而 wrapper2Fun 期望传递一个指向 Wraper2< 的指针。但是您实际上是将指向 ThreadWrapper 的指针传递给每个,这是完全不同的类型,所以它出错了。

使用 void * 和强制转换可以防止编译器指出您的类型错误。我建议使用类型安全的 C++ 线程库而不是原始的 pthread。 Boost 有一个,C++11 的标准库也是如此。

您对 auto_ptr 的使用充其量也是有问题的。它已被弃用,容易出错,并且表达所有权的方式很差 - 更喜欢 unique_ptrshared_ptr

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

无论如何,没有明显的理由将这些对象中的任何一个放在堆上。如果这样做,您需要决定内存的所有权所在。

关于c++ - 用于使用类对象引用的 C++ 类函数的 Pthread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32536427/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com