live555学习(二十一) --多线程

先看live555官网的回答:

Is this code 'thread safe'? I.e., can it be accessed by more than one thread at the same time?

Short answer: No. As noted above , the code assumes a single thread of execution, using an event loop - rather than multiple threads - for concurrency. This generally makes the code much easier to debug, and much easier to port across multiple operating systems, which may have different thread APIs, or no thread support at all. (For even stronger arguments along these same lines, see John Ousterhout's presentation.)

Longer answer: More than one thread can still use this code, if only one thread runs the library code proper, and the other thread(s) communicate with the library only by setting global 'flag' variables (such as event loop 'watch variables'), or by calling 'event triggers'.

Another possible way to access the code from multiple threads is to have each thread use its own "UsageEnvironment" and "TaskScheduler" objects, and thus its own event loop. The objects created by each thread (i.e., using its own "UsageEnvironment") must not interact (except via global variables). Such a configuration is not recommended, however; instead, it is safer to structure such an application as multiple processes, not multiple threads.

In any case, when using the "LIVE555 Streaming Media" code, you should be familiar with event-driven programming, and understand that an event-driven application can perform at least as well as one that uses threads (unless you're actually running on a multiprocessor, in which case it's usually simpler to have your application consist of multiple processes (not just threads) - one running on each processor). Note, in particular, that you do not need multiple threads in order to transmit (or receive) multiple streams concurrently.

 跟据它的说法,live555改多线程似乎不难,因为所有全局性的东西几乎都保存在UsageEnvironment的liveMediaPriv和groupsockPriv中,groupsockPriv里面放所有的GroupSock,而liveMediaPriv指向了一个HashTab类:_Tables,_Tables中有两个变量:mediaTable和socketTable.分别指向两个Hash Tab,mediaTable中存放所有从Meduim派生出来的类对象,socketTable存放的是StreamSocket们(我猜的,嘿嘿),比如SocketDescriptor.总之,全局性的东西们都放在UsageEnvironment内.


所以,如果开了多线程,为每个线程创建一个UsageEnvironment,然后调用各自UsageEnvironment的TaskSchedule的EventLoop(),理论上应该能实现各线程各自为战,互不干扰.但是RTSPServer却只能有一个,所以,各线程之间还必须有少量的交集.而且,RTSPServer最好单独放在一个线程中吧?因它总揽全局,所以正好放在主线程中.当然主线程也要有自己的UsageEnvironment和event loop.


如果真的实现了多线程,我们完全可以跟据CPU的数量确定线程的个数.那在什么时机,如何创建新线程呢?
想一下各RtspClientSession 的创建过程:RTSPServer收到新客户端请求后,先创建与客户对应的RTSPClientSession,RTSPClientSession在收到DESCRIBE请求后查找对应的ServerMediaSession,如果找不到,就创建一个新的,那么这几个对象的创建过程,从哪个开始进入新线程呢?
其实从RTSPClientSession开始,就可以放入新线程中,无非是RTSPServer要操作RTSPClientSession时进行同步保护而已.但是我还发现一个问题,那就是RTSPServer中并没有保存RTSPClientSession的列表.RTSPClientSession被创建出来就不管了,哦!从RTSPClientSession开始进入另外线程真是绝佳的时机!那RTSPClientSession被保存在哪里呢?它其实最终被保存在ServerMediaSusession的stremstate中了.当一个流播放完毕时,它自然就要被销毁了,是吧?


但是还有问题:RTSPServer中还担负者查找所有ServerMediaSession的任务,当然它是受RTSPClientSession委托的,因为ServerMediaSession们保存在RTSPServer中是理所当然的事.如果RTSPClientSession在不同的线程中呢?RTSPClientSession再查找ServerMediaSession就要进行同步保护了.还有个更严重的问题:我们希望把各个StreamState分散到不同的线程中,但它们又被保存在ServerMediaSub session中,麻烦又来了...


如果把ServerMediaSession保存到不同的线程中呢?看起来是可以的!但是又带来了问题,一个线程中的RTSPClientSession只能在自己线程的ServerMediaSession列表中查找是否已存在某个ServerMediaSession,其它线程中即使已存在了,也不能用,只能另创建一个,因为RTSPClientSession在被创建后应马上找到其UsageEnvironment,否则它就不能利用event loop接收数据了.所以ReuseSource是否能真正起作用,只能靠运气了.可不可以这样:先在主线程中执行RTSPClientSession的OPTION和DESCRIBE响应,再跟据其ServerMediaSession所在的线程,把它移到那个线程中去?我认为,这是完全能够做到的!看起来这样做,似乎有点完美了....
当然真正的实现上,如果能做到各线程之间的交互只是把DelayTask Handle放到目的线程的EventLoop中的话,并行计算的能力就真的要发挥出来了.
源自:http://blog.csdn.net/nkmnkm/article/details/7034414

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值