这个线程是在这里开始的,但是由于缺乏一个完整的好例子(并且为了避免删除所有那个问题),这里重写了它.
因此,在以下示例中,void cppthread::ThreadedFunc()
生成的gets作为单独的线程执行.相反,我宁愿void ThreadedWrite::ThreadedFunc()
被执行.我怎样才能做到这一点?(代码后面还有一些细节)
cppthread.hpp
#ifndef CPPTHREAD_HPP #define CPPTHREAD_HPP #includeusing namespace std; class cppthread { public: cppthread(); virtual ~cppthread(); virtual void threadedFunc(); ///parentObj (ie "this" pte from caller") is ///necessary in order to execute the correct ///threadedFunc() even when the derived class ///wants to spawn a thread. int spawn(void *parentObj = NULL); void terminate(); protected: pthread_mutex_t mtx; bool exitThread; private: /* add your private declarations */ int join(); pthread_t threadId; }; #endif /* CPPTHREAD_HPP */
cppthread.cpp
#include#include #include #include "cppthread.hpp" void* threadCallback(void* obj); cppthread::cppthread() { exitThread = false; pthread_mutex_init(&mtx, NULL); } cppthread::~cppthread() { if (!exitThread) terminate(); pthread_mutex_destroy(&mtx); } void cppthread::threadedFunc() { while ( !exitThread ) { printf("Hello from cppthread::threadfunc. This should not be run once derived and redefined.\n"); } if (exitThread) { printf("graceful exit from cppthread::threadfunc. This should not be run once derived and redefined.\n"); } pthread_exit((void*)0); } int cppthread::spawn(void* parentObj) { int ret; printf("parentObj = %p\n", parentObj); if (parentObj == NULL) { ret = pthread_create(&threadId, 0, &threadCallback, this); printf("cppthread_create with \"this\" \n"); } else { ret = pthread_create(&threadId, 0, &threadCallback, parentObj); printf("cppthread_create with parentObj\n"); } if (ret != 0) { printf("cppthread_create error\n"); exit(EXIT_FAILURE); } else { //printf("cppthread::threadID= %lu\n",threadId); } return ret; } void cppthread::terminate() { exitThread = true; join(); } int cppthread::join() { int status , ret; //printf("cppthread::join_threadID= %lu\n",threadId); ret = pthread_join(threadId,(void**)&status); if (ret != 0) { printf("cppthread_join error: "); switch (ret) { case EDEADLK: printf("deadlock\n"); break; case EINVAL: printf("thread not joinable\n"); break; case ESRCH: printf("threadID not found\n"); break; default : printf("unknown error\n"); break; } } return status; } //---------------------------------------------------------------------- void* threadCallback(void* obj) { static_cast (obj)->threadedFunc(); return(0); } // callback
threadedwrite.hpp
#ifndef THREADEDWRITE_HPP #define THREADEDWRITE_HPP #include "cppthread.hpp" using namespace std; class ThreadedWrite : public cppthread { public: ThreadedWrite(ThreadedWrite* mySelf); virtual ~ThreadedWrite(); void threadedFunc(); void rrdupdate_thread(); ///inherited significant members: from cppthread /// int spawn(); /// void terminate(); ///protected /// pthread_mutex_t mtx; /// bool exitThread; private: ThreadedWrite* instancePtr; }; #endif /* THREADEDWRITE_HPP */
threadedwrite.cpp
#include#include "threadedwrite.hpp" ThreadedWrite::ThreadedWrite(ThreadedWrite* mySelf):instancePtr(mySelf) { cout << "instancePtr = " << instancePtr << endl; } ThreadedWrite::~ThreadedWrite() { } void ThreadedWrite::threadedFunc() { if ( !exitThread ) { cout << "this is the ThreadedWrite::threadedFunc() running!" << endl; } else { cout << "ThreadedWrite::threadedFunc must exist now" << endl; } pthread_exit((void*)0); } void ThreadedWrite::rrdupdate_thread() { cout << "about to spawn" << endl; spawn(instancePtr); }
main.cpp中
#include#include "threadedwrite.hpp" using namespace std; //-------main body------------------------------------------------------ int main(int argc, char* argv[]) { ThreadedWrite thrrdupd(&thrrdupd); cout << "hello from main 1 " << &thrrdupd << endl; thrrdupd.rrdupdate_thread(); cout << "hello from main 2 " << &thrrdupd << endl; return 0; }
以上产生输出(对我来说):
instancePtr = 0x7fff39d17860 hello from main 1 0x7fff39d17860 about to spawn parentObj = 0x7fff39d17860 cppthread_create with parentObj hello from main 2 0x7fff39d17860 graceful exit from cppthread::threadfunc. This should not be run once derived and redefined.
因此,cppthread::spawn()
从派生类"ThreadedWrite"中执行上述调用,实际上提供了一个"this"指向指向的callback()
函数cppthread::ThreadedFunc()
,而不是ThreadedWrite::ThreadedFunc()
.
您还可以看到我尝试(通过"instancePtr"基础结构)将指向"ThreadedWrite"实例的指针传递回回调函数.但这也失败了.
此外,最好我想保持cppthread类尽可能通用,以便能够在可能的情况下使用它.
请注意,如果我从threadedwrite.cpp中删除"spawn(instancePtr)",并从main.cpp中调用spawn,就像这样
int main(int argc, char* argv[]) { ThreadedWrite thrrdupd(&thrrdupd); cout << "hello from main 1 " << &thrrdupd << endl; thrrdupd.rrdupdate_thread(); thrrdupd.spawn(); cout << "hello from main 2 " << &thrrdupd << endl; return 0; }
我得到的输出是预期的(和想要的),它看起来像这样:
instancePtr = 0x7ffd24b04ed0 hello from main 1 0x7ffd24b04ed0 about to spawn parentObj = (nil) cppthread_create with "this" hello from main 2 0x7ffd24b04ed0 this is the ThreadedWrite::threadedFunc() running!
Alan Stokes.. 5
在返回之前,您需要等待线程终止main
,因为这会破坏您的对象.
否则你有竞争条件:
线程已启动.
thrrdupd
当你离开时,你开始生气main
.
~ThreadedWrite
运行; 在这一点上,对象不再是一个ThreadedWrite
而是一个cppthread
.
~cppthread
运行并等待线程.
该线程调用回调,因为该对象现在具有动态类型cppthread
,因此cppthread::threadedFunc
被调用.
5.可能在3.之前发生,在这种情况下,您将获得预期的输出.
如果您确保等待线程在步骤3完成,那么它将正常工作.也许你可以terminate
在里面打电话~ThreadedWrite
?
在返回之前,您需要等待线程终止main
,因为这会破坏您的对象.
否则你有竞争条件:
线程已启动.
thrrdupd
当你离开时,你开始生气main
.
~ThreadedWrite
运行; 在这一点上,对象不再是一个ThreadedWrite
而是一个cppthread
.
~cppthread
运行并等待线程.
该线程调用回调,因为该对象现在具有动态类型cppthread
,因此cppthread::threadedFunc
被调用.
5.可能在3.之前发生,在这种情况下,您将获得预期的输出.
如果您确保等待线程在步骤3完成,那么它将正常工作.也许你可以terminate
在里面打电话~ThreadedWrite
?