當前位置:編程學習大全網 - 編程語言 - 如何用多任務處理 求助 c++

如何用多任務處理 求助 c++

在某些系統中,需要妳自己來構建自己的異步多任務處理框架。通過這種多任務處理,可以自己實現事件驅動編程模型的壹個小部分。當然,event driven is good for computer but not for human beings,人要是事件驅動,要麽他是消防隊員,要麽他很失敗,呵呵。另外,當存在典型的情況 “等待數據->處理數據->等待數據”循環時,用異步處理能夠大大增加系統的性能,尤其是出現數據和處理互相依賴的關系時。如:任務A的輸出數據是任務B的輸入,而B的輸出又是C的輸入,而且B和C在進行數據處理之前需要花費大量時間來做初始化,線性處理顯然會有性能瓶頸。采用異步處理能改善這種情況,當有多個處理器時性能將得到極大的提高。

本文描述的異步多任務是通過同壹進程內的調度器來調度該進程內多個異步任務,這些異步任務的真正執行是通過工作線程來完成。其模型為:各異步的任務發送請求後阻塞;當其請求的任務完成後,調度器喚醒該任務並執行相應的處理(也許會再次發送壹個請求)。這時壹個典型的生產者/消費者的問題:在調度器中,生產者是任務,而調度器是消費者。壹旦任務的請求完成,調度器則執行該任務。

處理流程

由於scheduler是在壹個進程中,因此需要先將scheduler安裝到進程中,然後將各異步任務添加到scheduler,之後,各異步任務發送第壹個請求等待完成。最後啟動scheduler,處理各個已經完成請求。如下圖所示:

任務

每個任務都應當繼承自同壹個基類以使得調度器可以以相同的方式處理他們。每個派生的任務都應當包含(至少)壹個異步操作(或所屬對象),該操作可以執行1~n次。每次異步操作完成之後,其Run()函數將被調用以進行後續處理。因此,任務至少應當具有壹個狀態成員用於指示該任務所處的狀態。當任務處理完畢之後,任務可以把自己從調度隊列中移出。由於添加任務到調度隊列的操作應當由調度器而不是任務本身來做,因此,不需要Add()操作。因此,任務類應當象這樣:

其中:

StartWorker()、Dequeue()都是由TaskBase來實現的:

int TaskBase::Dequeue()

{

Scheduler* sched = SchedulerInstance::GetInstance();

int ret = ErrNone;

m_Mutex->Lock();

if (sched && m_Status != TaskPending)

sched->Remove(this);

else

ret = ErrTaskBusy;

m_Mutex->Unlock();

return ret;

}

int TaskBase::StartWorker()

{

Scheduler* sched = SchedulerInstance::GetInstance();

int ret = ErrNone;

m_Mutex->Lock();

if (sched && (m_Status != TaskPending || m_Status != NotAvailable))

{

m_Worker->RunThread(this);

}

else

ret = ErrTaskBusy;

m_Mutex->Unlock();

return ret;

}

void TaskBase::CancelWorker()

{

Scheduler* sched = SchedulerInstance::GetInstance();

m_Mutex->Lock();

if (sched && m_Status == TaskPending)

{

m_Worker->Cancel();

m_Status = TaskCancelled;

}

m_Mutex->Unlock();

}

由於使用了工作線程來進行真正的異步操作,因此,應當有壹個靜態函數來作為線程的入口函數。

其實現為:

void WorkerThread::ThreadFunction(void* aData)

{

TaskBase* task = static_cast<TaskBase*>(aData);

if (task)

task->IssueRequest();

// Notify the Scheduler

Scheduler* sched = SchedulerInstance::GetInstance();

if (sched)

sched->Notify();

}

由於工作線程的實現與平臺相關,因此此處列出Linux平臺的典型實現:

void LinuxThread::RunThread(void* aData)

{

pthread_create(&m_TID, NULL, WorkerThread::ThreadFunction, aData);

Scheduler* sched = SchedulerInstance::GetInstance();

if (sched)

sched->Notify();

}

void LinuxThread::Cancel()

{

pthread_cancel(m_TID);

Scheduler* sched = SchedulerInstance::GetInstance();

if (sched)

sched->Notify();

}

  • 上一篇:形容人才的朋友圈文案
  • 下一篇:機械自動化專業學什麽 主要課程是什麽
  • copyright 2024編程學習大全網