嵌入式Linux中的进程同步无竞争态读写
下部件:共享数据一缓冲区组、操作一缓冲区的访问、进程一生产者消费者。 生产者一消费者问题的传统的信号量解决方案使用了2个信号量,分别用来表示缓冲区中的条目数和空闲槽的数目。当进程需要特定类型的资源时,它可以通过函数调用对相应的信号量进行减量操作;同样,当进程释放资源时,它可以通过函数调用来对相应的信号量进行增量操作。由于信号量永远不会降到零以下,所以进程不能使用不存在的资源。因此,始终将计数信号量初始化为开始时可用的资源数。 定义循环队列缓冲区存放待处理数据,控制台数据处理进程从该循环队列缓冲区中消费数据,并将该数据存储位标记为"废弃"。数据采集写进程仅能将数据存放于标记为"废弃"的循环队列缓冲区中,如图1所示。 在没有多个生产者或消费者的情况下,如果仔细实现,循环缓冲区就不需要锁。生产者是唯一允许修改写入索引以及该索引指向的数组位置的进程。只要写入者在更新写入索引之前将新的值保存到缓冲区,则读取者将始终看到一致的数据结构;同时,读取者是唯一可以访问读取索引以及该索引指向位置的数据的进程。只要确保两个指针不要互相重叠,生产者和消费者可以在无竟态的情况下访问该缓冲区,如图2所示。 对于只有单个生产者和消费者,通过使用修正的使用信号量方式的生产者一消费者问题模型解决方案来实现。 以上用信号量方式解决了优先缓冲区问题,信号量"empty"和"full"的值分别指示空和满的缓冲区的数量,如图3所示。缓冲区指针i和j用来确保缓冲区按先进先出的顺序提供并使用。只要系统中存在一些满的和空的缓冲区,数据更新进程和数据处理进程就能无竞态并发执行。笔者在华恒ARM嵌入式平台HHARM2410-R5上按照上述方案成功实现了用例测试。 3 讨论
在生产者一消费者同步中,由生产者创建资源,与单纯的读程序不同,消费者可以通过访问资源,将资源删除或销毁。由于生产者进程和消费者进程共享一个缓冲区,因此在插入和删除条目时必须同步。实现中必须避免表l所列的同步异常问题。
以上的结构设计,将生产者与消费者分别简化为一个。当存在多个生产者和消费者的情况时,可以上述修正的解决方案为基础,设计多个计数器来统计并行读者(reader)、并行写者(writer)、读者或待读者(pre_reader)、写者或待写者(pre_writer)的数量。计数器的值在进程中的相应位置进行增减。读者和写者在被允许阅读和写入之前必须被阻塞,这可以通过P操作来完成。当读者或写者在进程被阻塞时控制开始阅读或书写的条件并未满足。这些条件随着任意一个计数器值的变化而改变,所以,进程在完成阅读或书写后必须执行相应的V操作。
在实行多读、多写进程同步解决方案时,必须要避免不同计数器的竞争条件,因而必须在临界段(CS)中执行对允许读或写操作条件的检查。
- Linux嵌入式系统开发平台选型探讨(11-09)
- 基于Winodws CE的嵌入式网络监控系统的设计与实现(03-05)
- 嵌入式系统实时性的问题(06-21)
- 嵌入式实时系统中的优先级反转问题(06-10)
- 嵌入式Linux系统中MMC卡驱动管理技术研究(06-10)
- FPGA的DSP性能揭秘(06-16)