C++ C++;在子线程中删除

C++ C++;在子线程中删除,c++,object,pthreads,C++,Object,Pthreads,我的理解是,在对象内部启动线程时调用的函数不应该是类成员。最好的方法似乎是启动一个friend函数,它可以让您重新访问对象 通常,启动子线程的成员函数(以及父线程)可以继续,也可以返回。在我使用这种技术的每一种情况下,我都让launcher方法返回调用它的父线程中的应用程序;类似Qt线程的东西 当子线程完成其工作时,它所做的最后一件事是返回到friend函数,该函数本身返回到等待捕捉其返回的对象(pthread_koin或WaitForSingleEvent),或者,如果没有捕捉器,我猜您会说它

我的理解是,在对象内部启动线程时调用的函数不应该是类成员。最好的方法似乎是启动一个friend函数,它可以让您重新访问对象

通常,启动子线程的成员函数(以及父线程)可以继续,也可以返回。在我使用这种技术的每一种情况下,我都让launcher方法返回调用它的父线程中的应用程序;类似Qt线程的东西

当子线程完成其工作时,它所做的最后一件事是返回到friend函数,该函数本身返回到等待捕捉其返回的对象(pthread_koin或WaitForSingleEvent),或者,如果没有捕捉器,我猜您会说它不会返回

所以,问题来了。如果友元函数的返回没有捕获器,即父线程不在成员函数中,我可以安全地销毁从友元函数启动子线程的对象吗

编辑--------------------------------------------------------------------------

从回答中可以明显看出,我需要一个例子。我们要买窗户。与Linux没有什么不同。我遗漏了很多东西,比如类定义等等

  • Main在堆上创建SomeObject
  • Main调用so->run()并开始做其他事情
  • Run()启动运行SomeFriend()的子线程
  • SomeFriend()调用so->Worker()(that==so)
  • Worker()执行任何操作并返回SomeFriend()
  • 我可以在这里删除吗?i、 e.
    删除该

    您的内存管理代码应该已经是线程安全的(或者线程开始时会很危险!),所以free()本身应该可以。销毁也很好,只要您记住,其他人可能没有对该对象的引用,因为他们将指向一个已销毁的对象

    人们之所以说它不应该是类成员,是因为成员函数有一个典型的隐藏指针,它在字节级别上的处理方式也与其他参数不同,所以不能只将其作为一个带有额外参数的普通函数调用。这使得它通常与pthread_create和CreateThreadEx函数不兼容,这些函数具有所需的特定调用约定。这就是为什么您有一个bouncer static/global/friend函数来为您进行这种调用约定转换(而且可能非常透明,以至于您自己都没有注意到)。

    是的

    您的内存管理代码应该已经是线程安全的(或者线程开始时会很危险!),所以free()本身应该可以。销毁也很好,只要您记住,其他人可能没有对该对象的引用,因为他们将指向一个已销毁的对象


    人们之所以说它不应该是类成员,是因为成员函数有一个典型的隐藏指针,它在字节级别上的处理方式也与其他参数不同,所以不能只将其作为一个带有额外参数的普通函数调用。这使得它通常与pthread_create和CreateThreadEx函数不兼容,这些函数具有所需的特定调用约定。这就是为什么您有一个bouncer static/global/friend函数来为您进行调用约定转换(而且可能非常透明,以至于您自己都没有注意到)。

    没有内在的理由不将成员函数作为线程中的顶级函数启动。C++11处理得很好:

    struct S {
        void f();
    };
    
    S s;
    
    int main() {
        std::thread thr(&S::f, s);
        thr.join();
        return 0;
    }
    

    没有内在的理由不将成员函数作为线程中的顶级函数启动。C++11处理得很好:

    struct S {
        void f();
    };
    
    S s;
    
    int main() {
        std::thread thr(&S::f, s);
        thr.join();
        return 0;
    }
    

    要回答您编辑的问题,可以
    删除该问题
    但是,请记住,在调用
    so->run()
    之后,由于线程调度程序调度线程的方式,它调用的
    main()
    或任何函数在其逻辑的任何点上都可能没有有效的
    so


    调用
    so->run()
    后,将线程视为“拥有”
    so
    main()
    及其堆栈子体在没有保护逻辑的情况下不应再次接触
    ,因此

    要回答您编辑的问题,您可以
    删除它
    但是,请记住,在调用
    so->run()
    之后,由于线程调度程序调度线程的方式,它调用的
    main()
    或任何函数在其逻辑的任何点上都可能没有有效的
    so


    调用
    so->run()
    后,将线程视为“拥有”
    so
    main()
    及其堆栈子体在没有受保护的逻辑的情况下决不能再接触
    ,因此

    从技术上讲,您可以在对象的静态类成员函数中启动线程。但是,您将没有这个指针(因为它是一个静态函数)。它仍然有助于将线程保持在其上下文中,而不是在没有类类型的函数中运行。我需要this指针,所以我不记得静态方法位。您可以将this指针作为参数传递给线程入口函数,然后让线程入口函数看起来像这样:void MyClass::MyStaticMethod(void*arg){((MyClass*)arg)->MyNonStaticMethod();}+1@Jeremy Friesner告诉我该知道的事。叹气。从技术上讲,您可以在对象的静态类成员函数中启动一个线程。但是,您将没有这个指针(因为它是一个静态函数)。它仍然有助于将线程保持在其上下文中,而不是在没有类类型的函数中运行。我需要this指针,所以我不记得静态方法位