⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	pthread_attr_setdetachstate(&priv->_attr, PTHREAD_CREATE_JOINABLE);#ifdef	PTHREAD_STACK_MIN	if(stack && stack <=  _autostack)		pthread_attr_setstacksize(&priv->_attr, _autostack);	else if(stack > _autostack)	{		if(stack < PTHREAD_STACK_MIN)			stack = PTHREAD_STACK_MIN;		else	// align to nearest min boundry		{				salign = stack / PTHREAD_STACK_MIN;			if(stack % PTHREAD_STACK_MIN)				++salign;			stack = salign * PTHREAD_STACK_MIN;		}		if(stack && pthread_attr_setstacksize(&priv->_attr, stack))		{#ifdef	CCXX_EXCEPTIONS			switch(Thread::getException())			{			case throwObject:				throw(this);				return;#ifdef	COMMON_STD_EXCEPTION			case throwException:				throw(ThrException("no stack space"));				return;#endif			default:				return;			}#else			return;#endif		}	}#endif#ifndef	__FreeBSD__#ifdef	_POSIX_THREAD_PRIORITY_SCHEDULING#ifdef HAVE_SCHED_GETSCHEDULER#define	__HAS_PRIORITY_SCHEDULING__		if(pri)	{		struct sched_param sched;		int policy;		policy = sched_getscheduler(0);		if(policy < 0)		{#ifdef	CCXX_EXCEPTIONS			switch(Thread::getException())			{			case throwObject:				throw(this);				return;#ifdef	COMMON_STD_EXCEPTION			case throwException:				throw(ThrException("invalid scheduler"));				return;#endif			default:				return;			}#else			return;#endif		}		sched_getparam(0, &sched);		pri = sched.sched_priority - pri;		if(pri 	> sched_get_priority_max(policy))			pri = sched_get_priority_max(policy);		if(pri < sched_get_priority_min(policy))			pri = sched_get_priority_min(policy);		sched.sched_priority = pri;		pthread_attr_setschedpolicy(&priv->_attr, policy);		pthread_attr_setschedparam(&priv->_attr, &sched);	}	#endif // ifdef HAVE_SCHED_GETSCHEDULER#endif // ifdef _POSIX_THREAD_PRIORITY_SCHEDULING#endif // ifndef __FreeBSD__#ifdef	__HAS_PRIORITY_SCHEDULING__	if(!pri)	        pthread_attr_setinheritsched(&priv->_attr, PTHREAD_INHERIT_SCHED);             #else        pthread_attr_setinheritsched(&priv->_attr, PTHREAD_INHERIT_SCHED);             #endif	_parent = getThread();	priv->_throw = _parent->priv->_throw;	_cancel = cancelInitial;#endif // WIN32}#ifndef WIN32Thread::Thread(const Thread &th){	priv = new ThreadImpl(threadTypeNormal);	_parent = th._parent;	priv->_attr = th.priv->_attr;	_cancel = cancelInitial;	_start = NULL;	priv->_throw = th.priv->_throw;	priv->_suspendEnable = false;	setName(NULL);	//	sigset_t mask, newmask;//	int rc;////	pthread_sigmask(SIG_BLOCK, blocked_signals(&newmask), &mask);//	rc = pthread_create(&_tid, &_attr, exec_t(&ccxx_exec_handler), this);//	pthread_sigmask(SIG_SETMASK, &mask, NULL);//	if(rc && Thread::getException() == throwObject)//		throw(this);//#ifdef	COMMON_STD_EXCEPTION//	else if(rc && Thread::getException() == throwException)//		throw(ThrException("cannot start copy"));//#endif}#endif // ndef WIN32Thread::~Thread(){	if(!priv)		return;#ifndef	WIN32	if(this == &_mainthread)		return;#endif	if(priv->_type == threadTypeDummy)	{		delete priv;		priv = NULL;		return;	}	terminate();}void Thread::setName(const char *text){	if(text)		snprintf(_name, sizeof(_name), "%s", text);	else		snprintf(_name, sizeof(_name), "%ld", (long)getId());}	void Thread::initial(void){}void Thread::final(void){}void *Thread::getExtended(void){	return NULL;}void Thread::notify(Thread *){}bool Thread::isThread(void){	if(!priv)		return false;#ifdef WIN32	return ((priv->_tid == GetCurrentThreadId())) ? true : false;#else	return (priv->_tid == pthread_self()) ? true : false;#endif}bool Thread::isDetached(void){        if(!priv)                return false;#ifdef  WIN32	// win32 doesn't support detached threads directly	return priv->_detached;#else        int state;        pthread_attr_getdetachstate(&priv->_attr, &state);        if(state == PTHREAD_CREATE_DETACHED)                return true;        return false;#endif}cctid_t Thread::getId(void) const{	return priv->_tid;}bool Thread::isRunning(void){	if(!priv)		return false;#ifdef WIN32	return (priv->_tid != 0 && priv->_active) ? true : false;#else	return (priv->_tid != 0) ? true : false;#endif // WIN32}int Thread::start(Semaphore *st){	if(!priv)		return -1;#ifdef WIN32	if(priv->_active)		return -1;	_start = st;	priv->_hThread = (HANDLE)_beginthreadex(NULL, (unsigned)priv->_stack, (exec_t)&Execute, (void *)this, CREATE_SUSPENDED, (unsigned *)&priv->_tid);	if(!priv->_hThread) 	{		CloseHandle(priv->_cancellation);		priv->_cancellation = NULL;		return -1; 	}	setCancel(cancelInitial);	SetThreadPriority(priv->_hThread, priv->_priority);	ResumeThread(priv->_hThread);	priv->_active = true;	return 0;#else	if(priv->_tid)	{		if(_start)		{			_start->post();			return 0;		}		else			return -1;	}	_start = st;	return pthread_create(&priv->_tid, &priv->_attr, exec_t(&ccxx_exec_handler), this);#endif}int Thread::detach(Semaphore *st){	_parent = NULL;#ifdef WIN32	// win32 we emulate detach		if(!priv)		return -1;	priv->_detached = true;	if(!priv->_active)		return Thread::start(st);	else if(_start)		_start->post();	return 0;#else	int rtn;	if(!priv)		return -1;	if(priv->_tid)	{		pthread_detach(priv->_tid);		if(_start)		{				_start->post();		        pthread_attr_setdetachstate(&priv->_attr, PTHREAD_CREATE_DETACHED);			return 0;		}		return -1;	}	pthread_attr_setdetachstate(&priv->_attr, PTHREAD_CREATE_DETACHED);	_start = st;	rtn = pthread_create(&priv->_tid, &priv->_attr, exec_t(&ccxx_exec_handler), this);	if(!rtn && priv->_tid)		return 0;	return -1;#endif}void Thread::terminate(void){#ifdef WIN32	HANDLE hThread;	if(!priv)		return;	hThread = priv->_hThread;	if (!priv->_tid || isThread())	{		if( priv->_cancellation)			::CloseHandle(priv->_cancellation);      		if(hThread)            		::CloseHandle(hThread);		delete priv;		priv = NULL;      		return;	}	bool terminated = false;	if(!priv->_active && hThread != NULL)	{		// NOTE: add a test in testthread for multiple		// suspended Terminate		ResumeThread(hThread);		TerminateThread(hThread, 0);		terminated = true;	}	else if(hThread != NULL)	{		switch(_cancel)	{		case cancelImmediate:			TerminateThread(hThread, 0);			terminated = true;			break;		default:			SetEvent(priv->_cancellation);		}	}	if(hThread != NULL)	{		WaitForSingleObject(hThread, INFINITE);		CloseHandle(hThread);		hThread = NULL;	}// what if parent already exited?//	if(_parent)//		_parent->notify(this);	if(priv->_cancellation != NULL)		CloseHandle(priv->_cancellation);	priv->_cancellation = NULL;	priv->_tid = 0;	if(getThread() == this)		_self.setKey(DUMMY_INVALID_THREAD);	if (terminated)		final();#else	if(!priv)		return;        cctid_t jtid = priv->_jtid, tid = priv->_tid;	if(jtid && (pthread_self() != jtid))	{		pthread_join(jtid, NULL);		priv->_jtid = 0;	}	else if((pthread_self() != tid) && tid)	{		// in suspend thread cannot be cancelled or signaled		// ??? rigth		// ccxx_resume(priv->_tid);				// assure thread has ran before we try to cancel...		if(_start)			_start->post();		pthread_cancel(tid);		if(!isDetached())		{			pthread_join(tid,NULL);			priv->_tid = 0;		}	}        pthread_attr_destroy(&priv->_attr);#endif	delete priv;	priv = NULL;}void Thread::sync(void){#if defined(__MACH__) || defined(__GNU__)	Thread::exit();#else	Thread::sleep(TIMEOUT_INF);#endif}void Thread::exit(void){	if (isThread())	{		setCancel(cancelDisabled);#ifdef WIN32		close();		ExitThread(0);#else		pthread_exit(NULL);#endif // WIN32	}	}		void Thread::close(){	bool detached = isDetached();#if !defined(CCXX_SIG_THREAD_ALARM) && !defined(__CYGWIN32__) && !defined(__MINGW32__) && !defined(WIN32)	if(this == PosixThread::_timer)		PosixThread::_arm.leaveMutex();#endif	setCancel(cancelDisabled);//	if(_parent)//		_parent->notify(this);      	// final can call destructor (that call Terminate)	final();	// test if this class is self-exiting thread#ifdef WIN32	if (_self.getKey() == this)#else	if (ThreadImpl::_self.getKey() == this)#endif	{		if(priv)		{#ifndef	WIN32			priv->_jtid = priv->_tid;#else						priv->_active = false;#endif		}		joinSem.post();	}	// see if detached, and hence self deleting	if(detached)		delete this;}#ifndef WIN32inline void ThreadImpl::ThreadCleanup(Thread* th){	// close thread	// (freddy77) Originally I thougth to throw an exception for deferred	// for capture it and cleanup using C++ destructor	// this doesn't work out!! 	// Throwing exception here (in cleanup) core dump app	th->close();}static void ccxx_thread_cleanup(void* arg){	ThreadImpl::ThreadCleanup( (Thread*)arg );}inline void ThreadImpl::ThreadExecHandler(Thread *th){	ThreadImpl::_self.setKey(th);	sigset_t mask;	pthread_sigmask(SIG_BLOCK, blocked_signals(&mask), NULL);	th->priv->_tid = pthread_self();#if defined(HAVE_PTHREAD_MACH_THREAD_NP)	th->priv->_mach = pthread_mach_thread_np(th->priv->_tid);#elif defined(_THR_MACH)	th->priv->_mach = mach_thread_self();#endif	th->setCancel(Thread::cancelInitial);	// using SIGUSR3 do not enable suspend by default	th->setSuspend(Thread::suspendEnable);	th->yield();	if(th->_start)	{		th->_start->wait();		th->_start = NULL;	}	pthread_cleanup_push(ccxx_thread_cleanup,th);	th->initial();	if(th->getCancel() == Thread::cancelInitial)		th->setCancel(Thread::cancelDefault);	th->run();	th->setCancel(Thread::cancelDisabled);	pthread_cleanup_pop(0);	if(th->isDetached())		ThreadImpl::_self.setKey(NULL);	th->close();	pthread_exit(NULL);}// delete Thread class created for no CommonC++ threadinline void ThreadImpl::ThreadDestructor(Thread* th){	if (!th || th == DUMMY_INVALID_THREAD || !th->priv)		return;	if(!th->priv)		return;	if (th->priv->_type == threadTypeDummy)		delete th;}static void ccxx_thread_destructor(void* arg){	ThreadImpl::ThreadDestructor( (Thread*)arg );}static void ccxx_exec_handler(Thread *th){	ThreadImpl::ThreadExecHandler(th);}#endif // ndef WIN32#ifdef	CCXX_SIG_THREAD_CANCELvoid	Thread::setCancel(Cancel mode){	sigset_t	mask;	sigemptyset(&mask);	sigaddset(&mask, CCXX_SIG_THREAD_CANCEL);		switch(mode)	{	case cancelImmediate:		pthread_sigmask(SIG_UNBLOCK, &mask, NULL);		break;	case cancelInitial:	case cancelDisabled:	case cancelDeferred:		pthread_sigmask(SIG_BLOCK, &mask, NULL);		break;	}	_cancel = mode;}#elsevoid	Thread::setCancel(Cancel mode){#ifdef WIN32	switch(mode)		{	case cancelDeferred:	case cancelImmediate:		_cancel = mode;		yield();		break;	case cancelDisabled:	case cancelInitial:		_cancel = mode;	}#else	int old;	switch(mode)	{	case cancelImmediate:		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);		break;	case cancelDeferred:		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);		pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old);		break;	case cancelInitial:	case cancelDisabled:		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old);		break;	default:		return;	}	_cancel = mode;#endif // WIN32}#endifvoid	Thread::yield(void)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -