- 论坛徽章:
- 0
|
5可用积分
自己模仿java的线程类用c++封装了pthread,如下:
ThreadBase.h
- #ifndef __THREADBASE_H__
- #define __THREADBASE_H__
- #define THREAD_CALL
- typedef void* (*ThreadCall)( void* aArg );
- #include <pthread.h> //pthread API
- class ThreadBase
- {
- public:
- ThreadBase( bool aDetached = false );
- virtual ~ThreadBase();
- bool Start();
- pthread_t Id();
- int ErrorCode();
- void Join();
- bool IsJoinable();
- protected:
- virtual void Run(){};
- pthread_t iId;
- int iErrorCode;
- bool iDetached; //用来标识线程是否分离
- private:
- static void* THREAD_CALL ThreadFunc( void* aArg );
- };
- #endif /* __THREADBASE_H__ */
复制代码 ThreadBase.cpp
- #include <errno.h>
- #include <string.h> //strerror
- #include "ThreadBase.h"
- ThreadBase::ThreadBase( bool aDetached )
- :iErrorCode( 0 ),
- iDetached( aDetached )
- {
- }
- ThreadBase::~ThreadBase()
- {
- }
- void* THREAD_CALL ThreadBase::ThreadFunc( void* aArg )
- {
- ThreadBase* self = static_cast<ThreadBase*>( aArg );
- self->Run();
- //pthread_exit( (void*)0 );
- return NULL;
- /* return (void*)0;*/
- }
- bool ThreadBase::Start()
- {
- if ( iDetached ) {
- pthread_attr_t attr;
- iErrorCode = pthread_attr_init( &attr );
- if ( 0 != iErrorCode )
- return false;
- iErrorCode = pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
- if ( 0 != iErrorCode ) {
- pthread_attr_destroy( &attr );
- return false;
- }
- iErrorCode = pthread_create( &iId, &attr, ThreadFunc, this );
- pthread_attr_destroy( &attr );
- }
- else
- iErrorCode = pthread_create( &iId, NULL, ThreadFunc, this );
- return ( ( iErrorCode == 0 ) ? true : false );
- }
- pthread_t ThreadBase::Id()
- {
- return iId;
- }
- int ThreadBase::ErrorCode()
- {
- return iErrorCode;
- }
- bool ThreadBase::IsJoinable()
- {
- return !iDetached;
- }
- void ThreadBase::Join()
- {
- if ( !iDetached )
- pthread_join( iId, NULL );
- }
复制代码 子类Thread覆盖父类的Run方法:
- #include <stdlib.h>
- #include "ThreadBase.h"
- #include <iostream>
- using std::cerr;
- using std::endl;
- class Thread : public ThreadBase
- {
- public:
- Thread( bool aDetached ):ThreadBase( aDetached ){}
- protected:
- void Run();
- };
- void Thread::Run()
- {
- cerr << "ID=" << iId << endl;
- cerr << "Hello, world!" << endl;
- }
复制代码 在main方法中,以非分离状态启动线程之后,在main方法中调用sleep或线程对象的Join方法,线程运行正常:
- int main( int argc, char** argv )
- {
- Thread thd( false );
- thd.Start();
- sleep( 1 );
- return EXIT_SUCCESS;
- }
复制代码 或则:
- int main( int argc, char** argv )
- {
- Thread thd( false );
- thd.Start();
- thd.Join();
- return EXIT_SUCCESS;
- }
复制代码 若以分离状态启动线程,则必须在main方法中调用sleep函数,线程才能正常运行:
- int main( int argc, char** argv )
- {
- Thread thd( true );
- thd.Start();
- sleep( 1 );
- return EXIT_SUCCESS;
- }
复制代码 否则线程没有开始运行,进程已经退出,导致Run方法不能运行.
我在论坛上找到一篇帖子(详见:http://bbs.chinaunix.net/viewthread.php?tid=1650660),
有人说,如果以分离状态启动线程后,在main方法结尾去掉return,
调用pthread_exit( NULL ),线程能够正常运行.代码如下:
- #include <stdio.h>
- #include <pthread.h>
- void * thread_func(void * arg)
- {
- pthread_t id = pthread_self();
- printf("Thread 1 : %u start\n",id);
- sleep(10);
- fprintf(stderr,"Thread 1 :%u stop\n");
- return NULL;
- }
- int main( int argc, char** argv )
- {
- pthread_t thd1;
- int ret;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
- ret=pthread_create(&thd1,&attr,thread_func,NULL);
- pthread_attr_destroy(&attr);
- if(ret != 0)
- {
- printf("Create thread 1 error!\n");
- }
- printf("Thread 1 : %u\n",thd1);
- pthread_exit( NULL );
- }
复制代码 我模仿以分离状态启动线程的代码如下:
- int main( int argc, char** argv )
- {
- Thread thd( true );
- thd.Start();
- pthread_exit( NULL );
- }
复制代码 结果线程没有正常运行
为什么C的这种写法可以,而我的c++的就不行了?
是不是因为thd对象在主线程中创建,而主线程退出后把thd给销毁了?
大家知道原因是什么?或则有什么好的解决方案,谢谢!!!! |
最佳答案
查看完整内容
答案不是你知道了吗?“是不是因为thd对象在主线程中创建,而主线程退出后把thd给销毁了”-->是的.对象是在栈上分配的,每个线程有一个独立的栈。main完成后,对象就over了,况且跨越了各自线程的栈的边界去访问其他栈就有可能导致不正确的行为。如果new一个对象的话,就不能释放这块内存了.-->可以清理的,用pthread_cleanup_push.具体,google一下
|