999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

一種Linux系統下的線程通信方法

2017-11-01 17:14:41
計算機應用與軟件 2017年10期
關鍵詞:定義

王 天 偉

(天津通博視源技術有限公司 天津 300000)

一種Linux系統下的線程通信方法

王 天 偉

(天津通博視源技術有限公司 天津 300000)

提出一種結合數據和資源管理的線程通信方法,從數據結構上對消息進行定義和描述,并在此基礎上設計和實現具備消息供給/回收策略的消息工廠。每個消息的內部會維護一個棧式數據結構,用于存放需要傳遞給其他線程的數據;然后基于POSIX消息隊列實現用于傳遞消息的郵箱。發送線程從消息工廠取出一條消息并通過對數據棧進行壓棧操作將待發送數據提交給消息,然后將消息郵遞到郵箱里,接收線程從郵箱中取出消息并將數據依次從消息的數據棧中彈出,并在數據處理完成后將消息返還給消息工廠。

多線程通信 消息工廠 郵箱

0 引 言

在嵌入式應用領域,越來越多的系統設計方案采用了基于操作系統的軟件架構,將諸如任務調度、硬件資源管理、圖形界面等方面的功能交由操作系統管理。而應用軟件設計本身只需關注與系統數據流相關的業務邏輯和資源調度即可。Linux系統是一個開源的操作系統,底層驅動越來越完善,在各個行業也都有比較成熟的開源軟件庫,因而基于Linux系統的開發具有軟件開發資源豐富、系統成本低、可定制程度高等特點。多線程常常是軟件設計中不可回避的問題,線程任務規劃、線程之間的同步和數據交互方式往往是實現過程中的一個難點,尤其會對后期的調試和維護帶來重大的影響。本文從基于數據流的角度出發,提出了一種Linux系統下的多線程通信方法,并對其實現細節進行了詳細的論述。

1 消息與消息工廠

一般出于對系統成本的考慮,應用軟件可使用的物理資源往往是有限的,因而在設計的過程中必須要考慮對與數據相關資源的回收和重復使用的問題。此外,對于數據發送線程來說其職能只是將數據發送出去,并不關心數據接收線程拿到數據會以何種方式進行處理(直接進行數據處理或是轉發給其他線程)以及數據處理完成的時刻。而且還可能存在多個線程同時(多核處理器)對同一數據進行處理的情況。各線程對數據的處理時間可能各不相同,因而較難確定釋放資源的時間,所以需要實現一種通知機制,保證應用軟件能夠捕獲任意消息所攜帶的數據被處理完成的時刻,以便進一步進行相關處理。這里借用工廠模式設計思想設計一個具備消息供給/回收機制的消息工廠,其功能如下:

1) 能夠實時提供消息給發送線程使用,發送線程得到消息后可向消息中添加數據項;

2) 工廠的供給能力(支持的最大消息數)及消息可攜帶的數據項的數量可配置;

3) 接收線程可實時將消息歸還給消息工廠以實現對消息的回收,同時保證工廠在回收消息期間能夠自動釋放與消息內各數據項相關聯的資源;

4) 各資源釋放完成后發出通知,告知消息所攜帶的數據已被處理完成,以便應用程序作相關處理。

1.1 消息的定義

定義消息的數據結構:

struct message

{

__s32 id;

__s32 prio;

struct msg_ops *ops;

__s32 (*cb_finish)(void *msg);

__s32 *cb_finish_arg;

void **resource;

void (**release)(void *data);

struct msg_payload *payload;

__s32 payload_num;

__s32 cur_payload_idx;

void *node;

};

結構中各成員含義如表1所示。

表1 消息結構描述

續表1

結構struct msg_ops用于描述對消息中數據的操作方法,其定義如下:

struct msg_ops

{

__s32 (*push)(void *msg, void *data,

__u32 len,

void (*release)(void *resource),

void *resource);

void* (*pop)(void *msg, __s32 *len);

__s32 (*count)(void *msg);

};

表2 對消息中數據的操作方法

結構struct msg_payload用于描述一個數據項,其定義如下:

struct msg_payload

{

void *data;

__s32 len;

};

表3 消息中數據項

1.2 消息工廠的定義和初始化

用一個全局鏈表描述消息工廠,定義如下:

struct list_head

{

struct list_head *next;

struct list_head *prev;

void *owner;

};

其中owner指向消息,next指向工廠中下一條消息的node成員(見struct message的定義),實際上node的類型是struct list_head;prev指向工廠中上一條消息的node成員。

消息工廠是由一個struct list_head類型的根節點和若干條struct message類型的消息組成的,根節點的prev指向根節點本身,根節點的next指向消息工廠內第一條消息;每條消息內部有存在一個node節點,其prev指向工廠中上一個消息節點(對于第一條消息,其prev指向根節點),next指向工廠中下一個消息節點(對于最后一條消息,其next指向根節點)。

消息工廠內數據組織關系如圖1所示。

圖1 消息工廠數據組織關系

定義函數message_factory_create實現(創建消息工廠):

__s32 message_factory_create(__u32 msg_num,

__u32 payload_num)

參數:

msg_num:工廠支持的消息的個數;

payload_num:消息內數據項的個數。

成功返回0,失敗返回-1。

創建消息工廠將依次完成以下工作:

1) 創建根節點(以下稱其為“全局鏈表”),并將其prev和next賦值為根節點的首地址;

2) 創建msg_num個消息(為struct message分配內存),為每個消息創建可以容納payload_num個數據項的數據棧;

3) 創建兩個指針數組,分別用于存放與payload_num個數據項相對應的資源及其釋放方法;

4) 將各個消息依次加入到全局鏈表中。

上述過程的執行流程如圖2所示。

圖2 創建消息工廠

1.3 供給消息

定義函數msg_factory_provide(生產消息):

struct message *msg_factory_provide (__s32 id,

__s32 prio)

參數:

id:郵箱id(指定消息將要進入的郵箱);

prio:指定消息在郵箱中的優先級別,接收線程總是先取得最高優先級的消息。

執行成功返回一條消息,否則返回空指針。

該函數從全局鏈表頭取出一個節點給發送線程,發送線程根據業務邏輯,向其中加入數據項。

1.4 回收消息

定義函數msg_factory_recycle(回收消息):

void message_factory_recycle(struct message *msg)

參數:

msg:待回收的消息。

該函數將消息對應的節點加到全局鏈表尾,接收線程在完成對消息處理后通過該函數實現對消息的回收。其流程如圖3所示。

圖3 消息回收流程

2 郵 箱

郵箱用于暫存消息,發送線程和接收線程之間通過郵箱進行數據交互,發送線程對從消息工廠中得到的消息進行加工,即將需要傳遞給接收線程的數據壓入消息的數據棧中,同時指定與各數據項相關聯的待釋放資源及其釋放方法,然后將消息發送到郵箱中;接收線程收到消息后依次將數據從數據棧中彈出,獲得各數據的首地址和有效字節長度,進而進行相應的數據處理,當所有數據處理完成后調用函數msg_factory_recycle將消息歸還給消息工廠。

這里基于POSIX消息隊列設計了郵箱模塊,具備以下功能:

1) 創建郵箱時可指定其名稱和可暫存的最大消息數;

2) 向郵箱發送消息時可提供超時時間,以保證當郵箱滿時,能夠及時釋放待發送數據相關資源能;

3) 當郵箱為空時接收線程阻塞;

4) 郵箱里有消息時,接收線程總是先得到當前優先級最高的消息。

2.1 創建郵箱

定義函數mailbox_create(創建郵箱):

__s32 mailbox_create(char *name, __s32 msg_num_max)

參數:

name:郵箱名稱;

msg_num_max:郵箱內能夠存放的消息數;

執行成功返回新創建郵箱的id。

2.2 從郵箱接收消息

定義函數mailbox_pend(接收消息):

__s32 mailbox_pend(struct message *msg)

參數:

msg:存放接收消息;

郵箱為空時,接收線程會阻塞,直到有消息到達。

2.3 向郵箱發送消息

定義函數mailbox_post(發送消息),其原型如下:

__s32 mailbox_post(struct message *msg,

__u32 timeout)

參數:

msg:待發送消息

timeout:超時時間(單位:us)

郵箱未滿時,函數直接返回,否則發送線程阻塞,若在超時時間到達之前發送出去,函數返回0,否則返回-1。

2.4 Linux內核支持

在進行嵌入式Linux內核的剪裁或移植階段,需要保證內核中已開啟對POSIX消息隊列的支持,方法是查看內核編譯選項的“General setup->POSIX Message Queues”。

3 結 語

在Linux系統下有很多種方式可以用來實現線程之間的數據交互,比如共享內存、socket、System V IPC或直接使用POSIX消息隊列等。對于文中提到的方法,其優點在于能夠通過這樣一種方式從數據的角度出發,按照對數據處理方式或引用方式的不同將系統功能劃分為可獨立設計和維護的子功能模塊,業務邏輯清晰,而且線程之間的數據傳遞是“零拷貝”(拷貝的只是數據的首地址)的,所以消息傳遞帶來的時間開銷基本上是可以忽略不計的。這一線程通信方法已成功應用于某機器視覺類項目,運行穩定,性能表現良好。此外,文中提到的方法雖然是基于Linux系統進行設計,但也適用于其他操作系統,主要區別在于郵箱的實現,不同的操作系統對于郵箱的“底層”支持不同,需要進行一定的調整或封裝工作。

[1] Chris Simmonds.Mastering Embedded Linux Programming[M].Birmingham:Packt Publishing Ltd,2015:247-265.

[2] Alex González.Embedded Linux Projects Using Yocto Project Cookbook[M].Birmingham:Packt Publishing Ltd,2015:185-192.

[3] 史蒂文斯, 拉戈.UNIX環境高級編程[M].3版.北京:人民郵電出版社,2014:533-587.

[4] Steven J M,William C W.Java設計模式[M].2版.北京:電子工業出版社,2012:158-164.

[5] Texas Instruments Incorporated.TMS320C6000 DSP/BIOS 5.x Application Programming Interface (API) Reference Guide[EB/OL].2012.http://www.ti.com/lit/ug/spru403s/spru403s.pdf.

[6] 左飛.C++數據結構原理與經典問題求解[M].北京:電子工業出版社,2008:153-199.

[7] 閻宏.Java與模式[M].北京:電子工業出版社,2002:127-142.

[8] Scott Meyers.Effective C++[M].3版.北京:電子工業出版社,2006:61-75.

[9] Bruce Powel Douglass.C嵌入式編程設計模式[M].北京:機械工業出版社,2012:116-198.

[10] Texas Instruments Incorporated.SYS/BIOS (TI-RTOS Kernel) v6.46 User’s Guide[EB/OL].2016.http://www.ti.com/lit/ug/spruex3q/spruex3q.pdf.

AMETHODOFCOMMUNICATIONBETWEENTHREADSUNDERLINUXSYSTEM

Wang Tianwei

(TianjinTongboshiyuanTechnologyCo.,Ltd.,Tianjin300000,China)

A multi-thread communication method based on data and resource management is proposed. The concept of message is defined by a data structure, on the basis of which a message factory with supply/recycling strategy is designed and realized. First, each message maintained a stack of data structure, which was used to store the data that need to be passed to other threads. Afterwards, the mailbox based on POSIX message queue was implemented for passing messages. The sending thread took a message from the message factory and the data was submitted to the message by pushing onto a data stack. Then the message would be sent to a mailbox. The receiving thread fetched a message from the mailbox and popped the data sequentially from the message stack. At last the message would be returned to the message factory after the data had been processed.

Multi-thread communication Message factory Mailbox

TP3

A

10.3969/j.issn.1000-386x.2017.10.059

2016-09-01。王天偉,碩士,主研領域:工控軟件。

猜你喜歡
定義
以愛之名,定義成長
活用定義巧解統計概率解答題
例談橢圓的定義及其應用
題在書外 根在書中——圓錐曲線第三定義在教材和高考中的滲透
永遠不要用“起點”定義自己
海峽姐妹(2020年9期)2021-01-04 01:35:44
嚴昊:不定義終點 一直在路上
華人時刊(2020年13期)2020-09-25 08:21:32
定義“風格”
成功的定義
山東青年(2016年1期)2016-02-28 14:25:25
有壹手——重新定義快修連鎖
修辭學的重大定義
當代修辭學(2014年3期)2014-01-21 02:30:44
主站蜘蛛池模板: 波多野结衣一二三| 91外围女在线观看| 久草青青在线视频| 日韩欧美综合在线制服| 国产福利小视频在线播放观看| 欧美国产日韩一区二区三区精品影视| 亚洲美女久久| 日韩欧美国产三级| 色婷婷久久| 亚洲成a人片| 波多野结衣视频一区二区| 欧美色综合网站| 欧美a级完整在线观看| 日本成人福利视频| 中文字幕免费视频| 中文字幕欧美日韩| 97久久精品人人做人人爽| 伊大人香蕉久久网欧美| 国产欧美日韩va另类在线播放| 日本欧美中文字幕精品亚洲| 免费国产福利| 国产性生交xxxxx免费| 国产女人水多毛片18| 一级毛片在线播放| 中文字幕无线码一区| 2019国产在线| 性做久久久久久久免费看| 国模极品一区二区三区| 国产成人综合日韩精品无码不卡| 国产jizz| 国产精品无码AⅤ在线观看播放| 国产成年女人特黄特色大片免费| 日韩A∨精品日韩精品无码| 亚洲熟妇AV日韩熟妇在线| 国产女同自拍视频| 国产精品区网红主播在线观看| 亚洲精品在线观看91| 亚洲男人在线天堂| 58av国产精品| 呦视频在线一区二区三区| 青青草原国产免费av观看| 欧美成人免费一区在线播放| 色天堂无毒不卡| 亚洲综合二区| 国产精品尤物在线| 99re热精品视频国产免费| 国产女人在线| 最近最新中文字幕在线第一页| 色欲色欲久久综合网| 国产精品亚洲一区二区三区在线观看| 一级毛片高清| 一级香蕉视频在线观看| 国产亚洲精品自在线| 人妻出轨无码中文一区二区| 欧美午夜精品| www.99在线观看| 40岁成熟女人牲交片免费| 国产在线精品99一区不卡| 欧美色99| 亚洲视频色图| 国产97视频在线观看| 亚洲v日韩v欧美在线观看| 91久久偷偷做嫩草影院精品| 亚洲欧美极品| 免费精品一区二区h| 国产91无码福利在线| 国产精品久久自在自2021| 国产在线视频导航| 国产人在线成免费视频| 欧美伊人色综合久久天天| 中文字幕亚洲精品2页| 亚洲天堂高清| 亚洲免费黄色网| 日本一本正道综合久久dvd| 欧美日本在线| 久久国产精品波多野结衣| 又爽又黄又无遮挡网站| 久久久久久高潮白浆| 国产精品永久在线| 国产va在线观看免费| 五月天福利视频| 亚洲日产2021三区在线|