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

📄 thread.cpp

📁 可用该程序将avi的电影文件转化为TS流
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** thread.cpp: thread management*-------------------------------------------------------------------------------* (c)1999-2001 VideoLAN* $Id: thread.cpp,v 1.7 2002/07/12 18:09:36 massiot Exp $** Authors: Benoit Steiner <benny@via.ecp.fr>** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version 2* of the License, or (at your option) any later version.** This program 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* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.**------------------------------------------------------------------------------*********************************************************************************///------------------------------------------------------------------------------// Preamble//------------------------------------------------------------------------------#include "defs.h"#ifdef PTHREAD_COND_T_IN_PTHREAD_H#include <pthread.h>#include <semaphore.h>#include <errno.h>#elif defined WIN32#include <windows.h>#include <process.h>#endif#include <stdio.h>#include <string.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include "common.h"#include "string.h"#include "system.h"#include "exception.h"#include "list.h"#include "thread.h"#include "debug.h"#include "list.cpp"#define INT_TEST_COUNT 15      // Test count before calling interruption                               // process#define INT_TEST_DELAY 1000000 // Delay in microseconds between each test                               // before calling interruption process//******************************************************************************// Class C_ThreadKiller//******************************************************************************////******************************************************************************/*//------------------------------------------------------------------------------// //------------------------------------------------------------------------------class C_ThreadKiller{public:  // The thread is created detachable during the application startup. It will  // live until the end of the program  C_ThreadKiller();  ~C_ThreadKiller();  void Kill(C_Thread* pThread);protected:  // Main loop  static void* MainLoop(void* pThread);private:  bool m_bStop;#ifdef PTHREAD_COND_T_IN_PTHREAD_H  pthread_t tId;#elif defined WIN32  HANDLE hThread;  WORD dwId;#endif  E_Exception* m_pException;  C_Thread* m_pThread;  C_Mutex m_cLock;  C_Semaphore m_cJobAvailable;  C_Semaphore m_cJobDone;};//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_ThreadKiller::C_ThreadKiller() : m_cJobAvailable(0), m_cJobDone(0){  m_bStop = false;  m_pException = NULL;  m_pThread = NULL;  pthread_attr_t sAttr;  pthread_attr_init(&sAttr);  pthread_attr_setdetachstate(&sAttr, PTHREAD_CREATE_DETACHED);  int iRc = pthread_create(&tId, NULL, C_ThreadKiller::MainLoop, this);  pthread_attr_destroy(&sAttr);  ASSERT(!iRc);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_ThreadKiller::~C_ThreadKiller(){  m_bStop = true;  // End of the main loop. No need to lock because all threads must be  // destroyed at this point of the execution.  m_pThread = NULL;  m_cJobAvailable.Post();  // Cleaning  void* pRc = NULL;  int iRc = pthread_join(tId, &pRc);  ASSERT(!iRc);  ASSERT(!pRc);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void* C_ThreadKiller::MainLoop(void* pThread){  C_ThreadKiller* pThis = (C_ThreadKiller*)pThread;  while(!pThis->m_bStop)  {    // Wait for something to do    pThis->m_cJobAvailable.Wait();    // Do the job    if(pThis->m_pThread)    {      // Handle the request      try      {        pThis->m_pThread->Stop();      }      catch(E_Exception e)      {        pThis->m_pException = new E_Exception(e);      }      pThis->m_cJobDone.Post();    }    else      ASSERT(pThis->m_bStop);  }  return NULL;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_ThreadKiller::Kill(C_Thread* pThread){  ASSERT(pThread);  // Only one thread can be killed at a time for now  m_cLock.Lock();  // Process the request  m_pThread = pThread;  m_cJobAvailable.Post();  m_cJobDone.Wait();  // Get the exception if there was one  if(m_pException)  {     E_Exception e(*m_pException);     delete m_pException;     m_pException = NULL;     m_cLock.UnLock();     throw e;  }  else    m_cLock.UnLock();}*///******************************************************************************// Class C_Thread//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------// Instanciation of the static list of running threads and of the thread killer//------------------------------------------------------------------------------C_List<C_Thread> C_Thread::s_cThreadList;//C_ThreadKiller s_cThreadKiller;//------------------------------------------------------------------------------////------------------------------------------------------------------------------C_Thread::C_Thread(unsigned int iProperties){  m_iFlags = iProperties;  m_iStatus = THREAD_STATUS_NOTSTARTED;#ifdef PTHREAD_COND_T_IN_PTHREAD_H  ZERO(tId);#elif defined WIN32  ZERO(hThread);  ZERO(dwId);#endif}//------------------------------------------------------------------------------////------------------------------------------------------------------------------C_Thread::~C_Thread(){  // Verify that the thread has been stopped before  ASSERT(s_cThreadList.Find(*this) < 0);}//------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_Thread::Create(){   try  {    // Do some initialisations before starting the real job    InitWork();    // Now launch the thread#ifdef PTHREAD_COND_T_IN_PTHREAD_H    // Set the thread attributes. It is important for the thread to be created    // joinable unless the instance of the class could be destroyed before the    // end of the execution of DoWork     pthread_attr_t sAttr;    pthread_attr_init(&sAttr);    pthread_attr_setdetachstate(&sAttr, PTHREAD_CREATE_JOINABLE);    int iRc = pthread_create(&tId, NULL, C_Thread::StartRoutine, this);        pthread_attr_destroy(&sAttr);    #elif defined _WIN32    unsigned long threadID;    hThread = (HANDLE)CreateThread(NULL, 0,             (LPTHREAD_START_ROUTINE)C_Thread::StartRoutine, this, 0, &threadID);    int iRc = ( hThread ? 0 : 1 );#endif    if(iRc)    {      throw E_Exception(GEN_ERR, "Unable to start thread: " + GetErrorMsg());    }      // Reference the thread in the list of running threads    s_cThreadList.PushEnd(this);  }  catch(E_Exception e)  {    throw E_Exception(GEN_ERR, "Unable to create thread", e);  }}//------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_Thread::Cancel(){  try  {    // Ask for thread cancellation#ifdef PTHREAD_COND_T_IN_PTHREAD_H    int iRc = pthread_cancel(tId);#elif defined WIN32    int iRc = 0;#endif    if(iRc)      throw E_Exception(iRc, "Thread cancellation failed: " + GetErrorMsg());     // Now Stop the cancelled thread    Stop();  }  catch(E_Exception e)  {    throw E_Exception(GEN_ERR, "Error when cancelling thread", e);  }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Thread::Stop(){  try  {    // As all our threads are created joinable, we must ensure that the calling    // thread is a different thread to avoid a deadlock. So if a thread try to stop    // itself, we ask another thread (the killer) to do the job.
#ifdef PTHREAD_COND_T_IN_PTHREAD_H    if(pthread_self() == tId)#else    if (GetCurrentThread() == hThread)#endif    {      ASSERT(false);      //s_cThreadKiller.Kill(this);    }    // Don't join if not started    // It avoids exception's generation because pthread_join returns an error    // when the thread was not started.    else if(m_iStatus != THREAD_STATUS_NOTSTARTED)    {      // Ask the user work routine to stop its normal processing      StopWork();        // Try to join the thread in order to clean the resources it used and      // to synchronise the calling thread with the destruction of this thread      // Seems that there is a bug here in the libpthread: when the thread      // is cancelled, pRc is set to any value so that there is no way to get      // the return value of the DoWork method      // Ok, let's try again to see if the pb still occurs      E_Exception* p_eError = NULL;#ifdef PTHREAD_COND_T_IN_PTHREAD_H      int iRc = pthread_join(tId, (void**)&p_eError);#elif defined _WIN32      int iRc = 0;      WaitForSingleObject (hThread, INFINITE);#endif      if(iRc)      {        // Look at thre return code of the joined thread        ASSERT(p_eError);        E_Exception e(*p_eError);        delete p_eError;        throw e;      }      // Cleaning      CleanWork();      // Remove the thread from the list of running thread, but only if it has been      // successfully stopped. Do not delete it, this is the responsability of the      // user      int iThreadPos = s_cThreadList.Find(*this);      ASSERT(iThreadPos >= 0);      s_cThreadList.Remove(iThreadPos);    }  }  catch(E_Exception e)  {    throw E_Exception(GEN_ERR, "Unable to stop thread", e);  }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Thread::Interrupt(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H  int iRc = pthread_cancel(tId);#elif defined _WIN32  int iRc = 0;#endif  if(iRc)    throw E_Exception(GEN_ERR, "Unable to interrupt thread: " + GetErrorMsg());  m_iStatus = THREAD_STATUS_INTERRUPTED;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Thread::DelayedInterruption(){  if(m_iStatus == THREAD_STATUS_STARTED)  {    for(unsigned int ui = 0; (ui < INT_TEST_COUNT) &&                             (m_iStatus == THREAD_STATUS_STARTED); ui++)    {#ifdef WIN32      Sleep(INT_TEST_DELAY / 1000000);#else      usleep(INT_TEST_DELAY);#endif    }  }  if(m_iStatus == THREAD_STATUS_STARTED)  {    printf("Thread not stopped after %u s,"                " calling interruption process\n",           INT_TEST_COUNT * INT_TEST_DELAY / 1000000);    Interrupt();  }}//------------------------------------------------------------------------------

⌨️ 快捷键说明

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