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

📄 pthread.c++

📁 最新osg包
💻 C++
📖 第 1 页 / 共 2 页
字号:
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007  The Open Thread Group * * This library is open source and may be redistributed and/or modified under   * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or  * (at your option) any later version.  The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  * OpenSceneGraph Public License for more details.*///// PThread.c++ - C++ Thread class built on top of posix threads.// ~~~~~~~~~~~#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <unistd.h>#include <pthread.h>#if defined __linux || defined __sun || defined __APPLE__#include <string.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/unistd.h>#endif#if defined(__sgi)#include <unistd.h>#endif#if defined(__hpux)#include <sys/mpctl.h>#endif#if defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY) || defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)#    include <sched.h>#endif#if defined (__FreeBSD__) || defined (__APPLE__) || defined (__MACH__)	#include <sys/types.h>	#include <sys/sysctl.h>#endif#include <OpenThreads/Thread>#include "PThreadPrivateData.h"#include <iostream>using namespace OpenThreads;extern int errno;const char *OPENTHREAD_VERSION_STRING = "OpenThreads v1.2preAlpha, Posix Threads (Public Implementation)";#ifdef DEBUG# define DPRINTF(arg) printf arg#else# define DPRINTF(arg)#endif//-----------------------------------------------------------------------------// Initialize the static unique ids.//int PThreadPrivateData::nextId = 0;//-----------------------------------------------------------------------------// Initialize thread master priority level//Thread::ThreadPriority Thread::s_masterThreadPriority =                                          Thread::THREAD_PRIORITY_DEFAULT;bool Thread::s_isInitialized = false;pthread_key_t PThreadPrivateData::s_tls_key;struct ThreadCleanupStruct {    OpenThreads::Thread *thread;    volatile bool *runflag;};//-----------------------------------------------------------------------------// This cleanup handler is necessary to ensure that the thread will cleanup// and set its isRunning flag properly.//void thread_cleanup_handler(void *arg) {    ThreadCleanupStruct *tcs = static_cast<ThreadCleanupStruct *>(arg);    tcs->thread->cancelCleanup();    *(tcs->runflag) = false;}//-----------------------------------------------------------------------------// Class to support some static methods necessary for pthread's to work// correctly.//namespace OpenThreads {class ThreadPrivateActions {    //-------------------------------------------------------------------------    // We're friendly to Thread, so it can issue the methods.    //    friend class Thread;private:    //-------------------------------------------------------------------------    // pthreads standard start routine.    //    static void *StartThread(void *data) {	Thread *thread = static_cast<Thread *>(data);	PThreadPrivateData *pd =	    static_cast<PThreadPrivateData *>(thread->_prvData);                    if (pd->cpunum>=0)        {#if defined(__sgi)            pthread_setrunon_np( pd->cpunum );#elif defined(HAVE_PTHREAD_SETAFFINITY_NP) || defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY) || defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)            cpu_set_t cpumask;            CPU_ZERO( &cpumask );            CPU_SET( pd->cpunum, &cpumask );#if defined(HAVE_PTHREAD_SETAFFINITY_NP)            pthread_setaffinity_np( pthread_self(), sizeof(cpumask), &cpumask);#elif defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY)            sched_setaffinity( 0, sizeof(cpumask), &cpumask );#elif defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)            sched_setaffinity( 0, &cpumask );#endif#endif        }        	ThreadCleanupStruct tcs;	tcs.thread = thread;	tcs.runflag = &pd->isRunning;	// Set local storage so that Thread::CurrentThread() can return the right thing	int status = pthread_setspecific(PThreadPrivateData::s_tls_key, thread);	if (status)        {            printf("Error: pthread_setspecific(,) returned error status, status = %d\n",status);        }	pthread_cleanup_push(thread_cleanup_handler, &tcs);#ifdef ALLOW_PRIORITY_SCHEDULING	//---------------------------------------------------------------------	// Set the proper scheduling priorities	//	SetThreadSchedulingParams(thread);#endif // ] ALLOW_PRIORITY_SCHEDULING        pd->isRunning = true;        // release the thread that created this thread.        pd->threadStartedBlock.release();        thread->run();        pd->isRunning = false;	pthread_cleanup_pop(0);        return 0;    };    //-------------------------------------------------------------------------    // Print information related to thread schduling parameters.    //    static void PrintThreadSchedulingInfo(Thread *thread) {#ifdef ALLOW_PRIORITY_SCHEDULING // [	if(sysconf(_POSIX_THREAD_PRIORITY_SCHEDULING)) {	    int status, my_policy, min_priority, max_priority;	    struct sched_param my_param;	    status = pthread_getschedparam(thread->getProcessId(),					   &my_policy,					   &my_param);	    if(status != 0) {		printf("THREAD INFO (%d) : Get sched: %s\n",		       thread->getProcessId(),		       strerror(status));	    } else {		printf(		    "THREAD INFO (%d) : Thread running at %s / Priority: %d\n",		    thread->getProcessId(),		    (my_policy == SCHED_FIFO ? "SCHEDULE_FIFO"		     : (my_policy == SCHED_RR ? "SCHEDULE_ROUND_ROBIN"			: (my_policy == SCHED_OTHER ? "SCHEDULE_OTHER"			   : "UNKNOWN"))),		    my_param.sched_priority);		max_priority = sched_get_priority_max(my_policy);		min_priority = sched_get_priority_min(my_policy);		printf(		    "THREAD INFO (%d) : Max priority: %d, Min priority: %d\n",		    thread->getProcessId(),		    max_priority, min_priority);	    }	} else {	    printf(		"THREAD INFO (%d) POSIX Priority scheduling not available\n",		thread->getProcessId());	}	fflush(stdout);#endif // ] ALLOW_PRIORITY_SCHEDULING    }    //--------------------------------------------------------------------------    // Set thread scheduling parameters.  Unfortunately on Linux, there's no    // good way to set this, as pthread_setschedparam is mostly a no-op.    //    static int SetThreadSchedulingParams(Thread *thread) {	int status = 0;#ifdef ALLOW_PRIORITY_SCHEDULING // [	if(sysconf(_POSIX_THREAD_PRIORITY_SCHEDULING)) {	    int th_policy;	    int max_priority, nominal_priority, min_priority;	    sched_param th_param;	    pthread_getschedparam(thread->getProcessId(),				  &th_policy, &th_param);#ifndef __linux__	    switch(thread->getSchedulePolicy()) {	    case Thread::THREAD_SCHEDULE_FIFO:		th_policy = SCHED_FIFO;		break;	    case Thread::THREAD_SCHEDULE_ROUND_ROBIN:		th_policy = SCHED_RR;		break;	    case Thread::THREAD_SCHEDULE_TIME_SHARE:		th_policy = SCHED_OTHER;		break;	    default:#ifdef __sgi		th_policy = SCHED_RR;#else		th_policy = SCHED_FIFO;#endif		break;	    };#else	    th_policy = SCHED_OTHER;  // Must protect linux from realtime.#endif#ifdef __linux__	    max_priority = 0;	    min_priority = 20;	    nominal_priority = (max_priority + min_priority)/2;#else	    max_priority = sched_get_priority_max(th_policy);	    min_priority = sched_get_priority_min(th_policy);	    nominal_priority = (max_priority + min_priority)/2;#endif	    switch(thread->getSchedulePriority()) {	    case Thread::THREAD_PRIORITY_MAX:		th_param.sched_priority = max_priority;		break;	    case Thread::THREAD_PRIORITY_HIGH:		th_param.sched_priority = (max_priority + nominal_priority)/2;		break;	    case Thread::THREAD_PRIORITY_NOMINAL:		th_param.sched_priority = nominal_priority;		break;	    case Thread::THREAD_PRIORITY_LOW:		th_param.sched_priority = (min_priority + nominal_priority)/2;		break;	    case Thread::THREAD_PRIORITY_MIN:		th_param.sched_priority = min_priority;		break;	    default:		th_param.sched_priority = max_priority;		break;	    }	    status = pthread_setschedparam(thread->getProcessId(),					   th_policy,					   &th_param);	    if(getenv("OUTPUT_THREADLIB_SCHEDULING_INFO") != 0)		PrintThreadSchedulingInfo(thread);	}#endif // ] ALLOW_PRIORITY_SCHEDULING	return status;    };};}//----------------------------------------------------------------------------//// Description: Set the concurrency level (no-op)//// Use static public//int Thread::SetConcurrency(int concurrencyLevel) {#if defined (HAVE_PTHREAD_SETCONCURRENCY)    return pthread_setconcurrency(concurrencyLevel);#else    return -1;#endif}//----------------------------------------------------------------------------//// Description: Get the concurrency level//// Use static public//int Thread::GetConcurrency() {#if defined (HAVE_PTHREAD_GETCONCURRENCY)    return pthread_getconcurrency();#else    return -1;#endif}//----------------------------------------------------------------------------//// Decription: Constructor//// Use: public.//Thread::Thread() {    if(!s_isInitialized) Init();    PThreadPrivateData *pd = new PThreadPrivateData();    pd->stackSize = 0;    pd->stackSizeLocked = false;    pd->idSet = false;    pd->isRunning = false;    pd->isCanceled = false;    pd->uniqueId = pd->nextId;    pd->nextId++;    pd->threadPriority = Thread::THREAD_PRIORITY_DEFAULT;    pd->threadPolicy = Thread::THREAD_SCHEDULE_DEFAULT;    pd->cpunum = -1;    _prvData = static_cast<void *>(pd);}//----------------------------------------------------------------------------//// Decription: Destructor//// Use: public.//Thread::~Thread(){    PThreadPrivateData *pd = static_cast<PThreadPrivateData *>(_prvData);    if(pd->isRunning)    {        std::cout<<"Error: Thread "<<this<<" still running in destructor"<<std::endl;	//---------------------------------------------------------------------	// Kill the thread when it is destructed	//	cancel();    }    delete pd;        _prvData = 0;}Thread *Thread::CurrentThread(){    if(!s_isInitialized) Thread::Init();    Thread *thread =	static_cast<Thread *>(pthread_getspecific(PThreadPrivateData::s_tls_key));    return thread;}//-----------------------------------------------------------------------------//// Description: Initialize Threading//// Use: public.//void Thread::Init() {    if(s_isInitialized) return;    // Allocate a key to be used to access thread local storage    int status = pthread_key_create(&PThreadPrivateData::s_tls_key, NULL);    if (status)    {        printf("Error: pthread_key_create(,) returned error status, status = %d\n",status);    }#ifdef ALLOW_PRIORITY_SCHEDULING    //--------------------------------------------------------------------------    // If we've got priority scheduling, set things to nominal.    //    if(sysconf(_POSIX_THREAD_PRIORITY_SCHEDULING)) {	int max_priority, nominal_priority, min_priority;	int th_policy;	sched_param th_param;	pthread_getschedparam(pthread_self(),			      &th_policy, &th_param);	max_priority = sched_get_priority_max(th_policy);	min_priority = sched_get_priority_min(th_policy);	nominal_priority = (max_priority + min_priority)/2;	th_param.sched_priority = nominal_priority;	pthread_setschedparam(pthread_self(),			      th_policy,			      &th_param);	s_masterThreadPriority = Thread::THREAD_PRIORITY_NOMINAL;    } else {	s_masterThreadPriority = Thread::THREAD_PRIORITY_DEFAULT;    }#endif // ] ALLOW_PRIORITY_SCHEDULING    s_isInitialized = true;}//-----------------------------------------------------------------------------//// Description: Get a unique identifier for this thread.//// Use: public//int Thread::getThreadId() {    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);    return pd->uniqueId;

⌨️ 快捷键说明

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