1. 程式人生 > >Live555 的一個缺陷--例子不能支援多執行緒(已經修改成支援多執行緒)

Live555 的一個缺陷--例子不能支援多執行緒(已經修改成支援多執行緒)

1)我對Live555進行了一次封裝,但是Live555 是單執行緒的,裡面定義的全域性變數太多,我封裝好dll庫後,在客戶端呼叫,因為多個對話方塊中要使用碼流,我就定義了多個物件從裝置端接收碼流,建立多個連線,但是當一路碼流退出,然後在退出另外的一路碼流時,庫裡面出現問題,原因是Live555 裡面的全域性變數被破壞了!

針對上面問題:我目前的解決辦法是將全域性的資訊隔離:

定義一個結構:

#define CLIENT_STREAM_NUM 4

class ourRTSPClient;

typedef struct  _RtspGlobal
{
 ourRTSPClient *pRtspClient;
 NetSdk *pNetSdk;
}RtspGlobal;

//
RtspGlobal struRtspGlobal[CLIENT_STREAM_NUM];

這樣每一路碼流對應陣列中的一項,就做成多執行緒的了,在全域性的回撥函式中,根據RTSPClient*rtspClient的指標和struRtspGloball陣列中的指標進行比較,如果相同,就知道是哪個流對應的連線了,比如在continueAfterSETUP函式裡面建立sink時,我們可以如下判斷:

  for (int i=0;i<CLIENT_STREAM_NUM;i++)
  {
   if (struRtspGlobal[i].pNetSdk!=NULL)
   {
    if (struRtspGlobal[i].pRtspClient==rtspClient)
    {
     scs.subsession->sink = CRtpMediaSink::createNew(env, *scs.subsession,
      (RtpMediaSinkCallback)struRtspGlobal[i].pNetSdk->rtspDataCallback,
      (void *)&struRtspGlobal[i],RTPMEDAA_SINK_RECEIVE_BUFFER_SIZE, rtspClient->url());

     break;
    }
   }

  }

這樣使得testRtspClient例子支援到多執行緒了。

2)Live555 的斷網重連問題

1)重連死鎖

1.1)重連時如果將解碼回撥執行緒放在NetSdk裡面,使用兩個Event,當接受執行緒結束時,傳送接受執行緒結束的訊號,然後在解碼執行緒裡面判斷接收執行緒訊號 ,如果有訊號,就傳送一個退出解碼執行緒,傳送一個解碼結束的訊號;

1.2)當超時重連時,首先Stop碼流,然後Restart碼流;停止碼流時,將eventLoopWatchVariable=1;讓資料接收執行緒順利退出;同時在stop函式裡面等待解碼執行緒結束,

WaitForThreadExit(m_DecodeExitEvent);

這時會造成死鎖;因為Live555是單執行緒的,在超時函式中需要等待本執行緒的結束,造成死鎖;

解決辦法:

1)使用單獨的心跳執行緒來實現重連功能或者在回撥資料給客戶端的的解碼執行緒裡面實現重連功能;

2)網路斷開判斷方法 使用延遲佇列來判斷,初始化時候呼叫noteLiveness,然後每次收到Sink的一幀資料時,再次呼叫noteLiveness,這樣如果網路斷開,超時後,就能判斷出來;在資料接收執行緒的doEventLoop後面將重連標記置位:

    m_bReConnect=true;

3)斷網重連的工作不能放在livenessTimeoutTask這個函式裡面,不然會造成重連死鎖,因為live555是單執行緒的;只能放在其它的執行緒裡面實現重連;我是放在回撥給客戶端的解碼執行緒裡面實現重連;

void NetSdk::noteLiveness(void* clientData,UsageEnvironment& env)
{

 if (m_ReconnectTime> 0)
 {
  env.taskScheduler().rescheduleDelayedTask(fLivenessCheckTask,m_ReconnectTime*1000000,(TaskFunc*)livenessTimeoutTask, clientData);
 }


}


void NetSdk::livenessTimeoutTask(void* clientData) {

 TRACE("livenessTimeoutTask run\n");
 RtspGlobal *pRtspGlobal=(RtspGlobal *)clientData;
 pRtspGlobal->pNetSdk->fLivenessCheckTask= NULL;
 UsageEnvironment& env = pRtspGlobal->pRtspClient->envir(); // alias


 pRtspGlobal->pNetSdk->RestopVideo();


}

重連執行緒如下:

void NetSdk::DecodeThread(void *arg)
{
 NetSdk *pThis=(NetSdk*)arg;

 while (!pThis->m_bQuit)
 {

  if (pThis->m_bReConnect)
  {
   //
   pThis->RestartVideo();
   pThis->m_bReConnect=false;

  }else
  {
   pThis->ImageDecodeAndShow();
  }

 }

 SetEvent(pThis->m_DecodeExitEvent);

}

哪位有更好的辦法,不妨告訴我! 

相關推薦

Live555 的一個缺陷--例子不能支援執行(已經修改支援執行)

1)我對Live555進行了一次封裝,但是Live555 是單執行緒的,裡面定義的全域性變數太多,我封裝好dll庫後,在客戶端呼叫,因為多個對話方塊中要使用碼流,我就定義了多個物件從裝置端接收碼流,建立多個連線,但是當一路碼流退出,然後在退出另外的一路碼流時,庫裡面出現問題

0066 Linux中個Java檔案打包單個可執行jar檔案及其manifest.mf檔案編寫規則

現在我有三個Java類檔案:GuessGame.java Player.java GameLauncher.java(含主函式) 先用編譯命令: javac GuessGame.java Player

關於執行程式中使用volatile關鍵字的一個例子

在公司分配給我的爬蟲任務中,具體的資訊又寫需要在詳情頁中取得,所以需要在加入待抓取連結 我們用的框架是基於java 的webmagic ,這個框架可以在啟動時設定多個執行緒抓取,所以待抓取的多個連結可能是跑在不同執行緒上的,但是最後需要統計,一共抓取了多少條資訊,這就需要執行緒同步了。

python 執行程式設計(一個經典例子

python 多執行緒經典案例(摘自《python核心程式設計》) 使用佇列的資料結構,生產者生產商品,消費者選取商品,且時間均不固定 from random import randint from time import sleep from queu

Android實現執行下載檔案,支援斷點

本篇部落格主要介紹多執行緒去下載檔案,以下載多個app為例。不管去下在app,音視訊等檔案,實現起來都一樣。篇幅有點長,先貼張美女圖看看 正在下載的效果圖 下載完成效果圖 小編的下載路徑是放在sd卡的絕對路徑中,方便驗證! 工程目錄圖 介紹下每

java封裝FFmpeg命令,支援原生ffmpeg全部命令,實現FFmpeg程序處理與執行輸出控制(開啟、關閉、查詢),rtsp/rtmp推流、拉流

前言: 之前已經對FFmpeg命令進行了封裝http://blog.csdn.net/eguid_1/article/details/51787646,但是當時沒有考慮到擴充套件性,所以總體設計不是太好,需要改動的地方也比較多,也不支援原生ffmpeg命令,所以本次版本推翻

c#中子執行控制進度條的一個簡單例子

{          public  Form1()          ... {             InitializeComponent();         }          private void  button1_Click( object  sender, EventArgs e

C語言線程的一個簡單例子

color oid blog stdlib.h null bsp 等待 creat 多線程   多線程的一個簡單例子:    #include <stdio.h> #include <stdlib.h> #include <string.h&

實現一個支援執行時併發修改配置生效的Configuration類

可配置性是一個好的應用程式的重要指標。我們常常需要實現類似能夠執行時修改配置的功能。最近在開發一箇中間層的服務程式,最終釋出的方式是把程式碼打成jar包交給呼叫方使用。這個中間層服務需要一些配置資訊,考慮了一下有幾個基本的需求: 1. 在ja包中提供一個service-defalut.prope

執行基礎二(執行的啟動、終止,執行面臨的三種問題)

一、執行緒的啟動、終止方式   啟動: start native(呼叫外部介面啟動)     終止:    stop(類似kill,暴力終止)  interrupt 中斷的方式 通過指令的方式 volatile boolean stop

c/c++ 執行 ubuntu18.04 boost編譯與執行的坑

多執行緒 boost編譯與執行的坑 背景:因為要使用boost裡的多執行緒庫,所以遇到了下面的坑。 系統版本:ubuntu18.04 一,安裝boost 1,去boost官網下載 boost_1_XX_0.tar.gz 2,解壓 tar -zxvf boost_1_65_0.tar.gz 3

Java執行-併發之如何制定執行執行順序?

文章目錄 如何讓10個執行緒按照順序列印0123456789? 程式碼如下: 1.建立一個鎖物件類 2.建立一個執行緒類 3.測試類 如何讓10個執行緒按照順序列印012

java執行入門案例(2)之執行簡單應用

  上一篇文章:java多執行緒案例(1)之簡單銀行取款問題及其優化 我大概介紹了一下Java程式碼優化的問題,主要針對出學者而言,這一次我要介紹多執行緒應用的簡單案例 。網上有許多多執行緒的案例,但大多都挺複雜的,今天我主要目的也是介紹一下多執行緒應用的簡單案例,讓初學

乾貨!執行池+CountDownLatch,實現 執行併發計算、彙總

目錄結構 抽象類:求和器 單執行緒 求和器 VS 多執行緒 求和器 1)執行緒池 多個執行緒 一起併發執行,效能很生猛 2)CountDownLatch 主執行緒 使用 latch.await() 阻塞住,直到所有 子任務 都執行完畢了

Java——執行基本使用(四) 執行組和執行池的使用,工廠設計模式的使用

1.執行緒組的概述和使用 Java中使用ThreadGroup來表示執行緒組,它可以對一批執行緒進行分類管理,Java允許程式直接對執行緒組進行控制。            &n

Python中的執行程式設計,執行安全與鎖(一) 聊聊Python中的GIL 聊聊Python中的GIL python基礎之執行鎖機制 python--threading執行總結 Python3入門之執行threading常用方法

1. 多執行緒程式設計與執行緒安全相關重要概念 在我的上篇博文 聊聊Python中的GIL 中,我們熟悉了幾個特別重要的概念:GIL,執行緒,程序, 執行緒安全,原子操作。 以下是簡單回顧,詳細介紹請直接看聊聊Python中的GIL  GIL:&n

執行基礎(三)-執行併發安全問題

多執行緒基礎(三)-多執行緒併發安全問題 當多個執行緒併發操作同一資源時,由於執行緒切換實際不可控會導致操作邏輯執行順序出現混亂,嚴重時會導致系統癱瘓。例如下面的程式碼 public class SyncDemo { public static void main(Strin

Java執行(一) 什麼是執行

宣告:本系列大多是翻譯自https://www.javatpoint.com,加上自己的增刪改,盡力寫的系統而通俗易懂,後文不再重複宣告。 java的多執行緒是一個同時執行多個執行緒的過程。 執行緒是一個輕量級的子程序,是最小的處理單元。多執行緒和多程序都用於實現多工處理。 但是,我們使用多執

(四)執行說學逗唱:執行險惡,變數和執行安全不得不防

(一)多執行緒說學逗唱:關於執行緒那不得不說的二三事 (二)多執行緒說學逗唱:新手村偶遇Thread類 (三)多執行緒說學逗唱:村口的老R頭是個掃地僧(Runnable) 出了新手村,以後的路可就不那麼好走了,到底現在也是個江湖人,都必須經歷點困難挫折,要不以後拿什

Java5 執行(三)--Lock和Condition實現執行同步通訊

  1<Lock:   Lock比傳統執行緒模型中的Synchronied方式更加面向物件,與生活中的鎖類似,鎖本身也應該是一個物件.兩個執行緒執行的程式碼段要實現同步互斥的效果,它們必須用同一個Lock物件,鎖是在代表要操作的資源的類的內部方法中,而不是