NPAPI插件开发详细记录:再谈多线程

         前面提到过有关多线程的问题,主要是如何在插件中创建新的线程。但是在编写多个线程的插件过程中遇到的问题比如何创建一个线程要复杂得多。一个问题是多个线程之间共享数据,该问题其实就是普通的多线程编程中也会遇到,如果有丰富的多线程程序设计的经验,那么插件编写中多线程间共享数据的问题也不算什么复杂的问题了。简单提一下我的解决方法:我让多个线程间共享数据采用的方法是首先设计一个基础的数据类,其他要使用共享数据的类,都有一个成员指针指向这个公共数据类。基础类的对象在plugin类中的适当位置创建,并在适当的时候销毁。比如插件要使用两个线程来对音频数据进行接收和播放,首先创建一个基础类data。并设计一个receive类和一个player类来接收、播放音频数据。receive类有一个指针成员指向一个data对象,player类也有一个指针成员指向一个data对象。在plugin中开始接收数据之前,先new一个data对象:data* p=new data();然后用这个指针创建一个receive对象和一个player对象。接着调用receive类和player类的相关函数创建两个线程对音频数据进行接收与播放。当然这个过程中可以为data加上读写锁,是否必须加锁可以根据自己设计的公有数据类来决定,将指向共享数据的指针都设计成智能指针可以得到更好的效果。另外,上一节中提到的利用NPP结构的pdata就是指向plugin类的指针也可以很方便的实现多个类之间共享数据。
        上述做法基本上是可以正常工作的,但是有一个比较致命的缺点:刷新网页的时候页面中包含的插件实例都是要销毁并重新创建新的插件实例的,然而插件实例销毁了不能保证该实例创建的新的线程已经执行完毕并销毁,如果这些线程没有被销毁,而插件实例已经销毁了,此时线程中需要访问公共数据的指针都变得无效了,于是就会发生不可预料的错误,导致插件崩溃。
         这个问题折腾了我非常之久,后来得到高人指点,终于解决了这个问题,解决方法是利用一个event。在创建新的线程之前初始化一个event,而在插件要销毁之前reset这个event,然后等待所有插件中创建的插件退出。而在创建的新线程中需要花费大量时间的地方检查event的状态,如果检测到状态则退出当前执行循环,以使该线程尽快结束。直到所有新的线程都执行结束(销毁),再销毁插件实例。如此一来就解决了刷新网页时插件崩溃的问题。
        在解决上述问题过程中,接触到了boost库相关的一些东西,创建线程也可以使用boost库中的他thread库来创建线程,而boost库中的智能指针则表现出了更加优秀的效率。

你可能感兴趣的:(mozilla,插件,教程)