亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Apache APR可移植運行庫簡介(1)

2019-11-17 04:48:13
字體:
來源:轉載
供稿:網友
1.1 何為APR?
APR(Apache portable Run-time libraries,Apache可移植運行庫)的目的如其名稱一樣,主要為上層的應用程序提供一個可以跨越多操作系統平臺使用的底層支持接口庫。在早期的Apache版本中,應用程序本身必須能夠處理各種具體操作系統平臺的細節,并針對不同的平臺調用不同的處理函數。隨著Apache的進一步開發,Apache組織決定將這些通用的函數獨立出來并發展成為一個新的項目。這樣,APR的開發就從Apache中獨立出來,Apache僅僅是使用APR而已。目前APR主要還是由Apache使用,不過由于APR的較好的移植性,因此一些需要進行移植的C程序也開始使用APR,開源項目比如Flood loader tester(http://httpd.apache.org/test/flood/,該項目用于服務器壓力測試,不僅僅適用于Apache)、FreeSwitch(www.freeswitch.org),JXTA-C(http://jxta-c.jxta.org,C版本的JXTA點對點平臺實現);商業的項目則包括Blogline(http://www.bloglines.com/,covalent(http://www.covalent.net)等等。
APR使得平臺細節的處理進行下移。對于應用程序而言,它們根本就不需要考慮具體的平臺,不管是Unix、linux還是Window,應用程序執行的接口基本都是統一一致的。因此對于APR而言,可移植性和統一的上層接口是其考慮的一個重點。而APR最早的目的并不是如此,它最早只是希望將Apache中用到的所有代碼合并為一個通用的代碼庫,然而這不是一個正確的策略,因此后來APR改變了其目標。有的時候使用公共代碼并不是一件好事,比如如何將一個請求映射到線程或者進程是平臺相關的,因此僅僅一個公共的代碼庫并不能完成這種區分。APR的目標則是希望安全合并所有的能夠合并的代碼而不需要犧牲性能。
APR的最早的一個目標就是為所有的平臺(不是部分)提供一個公共的統一操作函數接口,這是一個非常了不起的目的,當然也是不現實的一個目標。我們不可能支持所有平臺的所有特征,因此APR目前只能為大多數平臺提供所有的APR特性支持,包括Win32、OS/2、BeOS、Darwin、Linux等等。為了能夠實現這個目標,APR開發者必須為那些不能運行于所有平臺的特性創建了一系列的特征宏(FEATURE MACROS)以在各個平臺之間區分這些特征。這些特征宏定義非常簡單,通常如下:
APR_HAS_FEATURE
假如某個平臺具有這個特性,則該宏必須設置為true,比如Linux和window都具有內存映射文件,同時APR提供了內存映射文件的操作接口,因此在這兩個平臺上,APR_HAS_MMAP宏必須設置,同時ap_mmap_*函數應該將磁盤文件映射為內存并返回適當的狀態碼。假如你的操作系統并不支持內存映射,那么APR_HAS_MMAP必須設置為0,而且所有的ap_mmap_*函數也可以不需要定義。第二步就是對于那些在程序中使用了不支持的函數必須提出警告。
目前APR中支持的基本類型包括下面幾種:
表3-1 APR中支持的基本類型
類型名稱
文件夾名稱
描述
atomic
/srclib/apr/atomic
原子操作
dso
/srclib/apr/dso
動態加載共享庫
file io
/srclib/apr/file_io

文件IO處理
mmap
/srclib/apr/mmap
內存映射文件
locks
/srclib/apr/locks
進程和線程互斥鎖
memory
/srclib/apr/memory
內存池操作
network_io
/srclib/apr/network_io
網絡IO處理
poll
/srclib/apr/poll
輪詢IO
table
/srclib/apr/tables
Apache數組(堆棧)和表格以及哈希表
process
/srclib/apr/threadproc
進程和線程操作
user
/srclib/apr/user
用戶和用戶組操作
time
/srclib/apr/time
時間操作
string
/srclib/apr/strings
字符串操作
passWord
/srclib/apr/passwd
終端密碼處理
misc
/srclib/apr/misc
大雜燴,不屬于其余類的任何apr類型都可以放在里面
shmem
/srclib/apr/shmem
共享內存

random
/srclib/apr/random
隨機數生成庫
每一個APR的實現我們都在后面會具體描述。
1.2 APR版本規則
由于Apache組織的目標是將APR獨立出來形成單獨的第三方庫,因此對其而言穩定的API接口就成為一個非常重要的必須考慮的方面。不過由于APR需要不斷的往前方展,因此API接口的變化又是必然的趨勢,因此如何平衡穩定性和變化性是APR開發者面臨的一個極需解決的問題。為此APR采用了嚴格的版本規則來實現這一點。用戶只需要簡單的判定APR版本號,就可以很輕易確定當前版本的兼容性:向前兼容、向后兼容還是前后同時兼容。
1.2.1版本概述
APR中使用三個整數來記錄APR版本號:MAJOR.MINOR.PATCH。MAJOR表示當前APR的主版本號,它的變化通常意味著APR的巨大的變化,比如體系結構的重新設計,API的重新設計等等,而且這種變化通常會導致APR版本的向前不兼容。MINOR稱之為APR的次版本號,它通常只反映了一些較大的更改,比如APR的API的增加等等,但是這些更改并不影響與舊版本源代碼和二進制代碼之間的兼容性。PATCH通常稱之為補丁版本,通常情況下假如只是對APR函數的修改而不影響API接口的話都會導致PATCH的變化。
目前為止APR的最高版本是1.2.2,最早遵循這種規則的版本號是0.9.0,不過在0.9.0之前,APR還推出了兩個版本a8和a9。不過有一點需要注重的是,我們后面描述的版本規則并不適合1.0.0以前的版本。對于1.0.0以前的版本(0.x.y),APR提供的API是可以任意的改變而沒有任何的限制,因此這些版本的變化不遵循后面描述的版本規則。從1.0.0以后的所有版本都遵循。切記。
除非主版本號發生變化,否則假如某個應用程序使用了低版本的APR,那么假如將該版本用高版本的APR替代,應用程序必須能夠無錯誤的編譯通過,通常我們稱之為前向兼容行;反之很明顯,假如應用程序中使用了高版本的APR,那么假如將該版本用低版本的APR替代,則未必能夠編譯通過,通常我們稱之為后向不兼容。
APR的發展中力圖總是保持與舊版本的源代碼和二進制版本之間的兼容性。通過源代碼兼容,應用程序就可以在使用新版本的APR進行編譯的時候不會報錯,這樣應用程序就不需要為了適應新的APR而做出調整,從而保持應用開發的一致性和持續性。除非APR的主版本號發生變更。這種兼容性反之則不成立。假如一個應用程序使用較高的MINOR版本開發,那么很明顯,假如將該版本替換為MINOR相對較低的版本進行編譯,則成功的可能性應該不是很大。
除了源代碼方面的兼容性,APR還希望能夠保持二進制之間的兼容性。通過保持二進制兼容,應用程序可以直接使用高版本的APR庫(或者是DLL,或者使so文件)替換低版本的庫文件,而不需要做任何修改,就可以鏈接成功。與源代碼兼容一樣,二進制的兼容也是向前兼容,而不保證向后兼容。
下面的表格演示了APR的版本規則策略:
原始版本
新版本
兼容性
原因
2.2.3
2.2.4
前后兼容
PATCH版本號的變化保持前向和后向兼容
2.2.3
2.2.1
前后兼容
PATCH版本號的變化保持前向和后向兼容
2.2.3
2.3.1
向前兼容
次版本號的變化保持向前兼容,但并不保持向后兼容

2.2.3
2.1.7
不兼容
次版本號的降低不能保證向后兼容
2.2.3
3.0.0
不兼容
主版本號的變化不保證兼容性
2.2.3
1.4.7
不兼容
主版本號的變化不保證兼容性
1.2.2版本策略
為了控制APR接口的穩定,APR制定了嚴格的版本變化策略。
1.2.2.1PATCH版本策略
在前表中我們看到,PATCH的變化并不影響版本的源代碼和二進制級別的兼容性,包括向前和向后兼容,因此,我們很輕易看出,PATCH版本變化通常意味著對版本的修修補補,即BUG的修復。這些工作通常被局限于函數內部的修改,或者是API函數內部,或者是APR內部static函數的變化。任何對API的增加、修改、刪除都是不答應的。
1.2.2.1次版本號策略
任何新函數,新變量以及新常量的引入以及任何現有函數的廢除都將可能導致次版本號的變化:
1)、新函數的引入
An application coded against an older minor release will still have all of its functions available with their original signatures. Once an application begins to use a new function, however, they will be unable to work against older minor versions.
It is tempting to say that introdUCing new functions might create incompatibility across minor releases. If an application takes advantage of an API that was introduced in version 2.3 of a library, then it is not going to work against version 2.2. However, we have stated that an any application built against version 2.2 will continue to work for all 2.x releases. Thus, an application that states "requires 2.3 or later" is perfectly acceptable -- the user or administrator simply upgrades the installed library to 2.3. This is a safe Operation and will not break any other application that was using the 2.2 library.
In other words, yes an incompatibility arises by mandating that a specific version needs to be installed. But in practice, this will not be a problem since upgrading to newer versions is always safe.
2)、新常量的引入
Similar to functions, all of the original (old) constants will be available to an application. An application can then choose to use new constants to pick up new semantics and features.
3)、函數替換
This gets a bit trickier. The original function must remain available at the link-level so that an application compiled against a minor version will continue to work with later minor versions. Further, if an application is designed to work with an earlier minor version, then we don't want to suddenly change the requirements for that application. This means that the headers cannot silently map an old function into a newer function, as that would turn an application, say, based on 1.2 into an application requiring the 1.4 or later release.

This means that functions cannot truly be replaced. The new, alternate function can be made available in the header and applications can choose to use it (and become dependent upon the minor release where the function appears).
It is possible to design a set of headers where a macro will always refer to the "latest" function available. Of course, if an application chooses to use this macro, then the resulting compiled-binary will be dependent upon whatever version it was compiled against. This strategy adds the new functionality for applications, yet retains the necessary source and binary compatibility for applications designed or built against previous minor releases.
Constants (enumerated values and preprocessor macros) are not allowed to change since an older application will still be using them. Similarly, function signatures at the link-level may not change, so that support for older, compiled applications is maintained.
4)、函數作廢
隨著APR的升級,APR中的一些API可能將作廢,不再使用,但是這些API并不能從APR庫中移除。因為一旦API被移除,向后兼容性將被破壞。因此我們能夠做的僅僅是公布其作廢。
If you deprecate a function in APR, please mark it as such in the function documentation, using the doxygen "/deprecated" tag. Deprecated functions can only be removed in major releases.
A deprecated function should remain available through the original header. The function prototype should remain in the same header, or if moved to a "deprecated functions" header, then the alternate header should be included by the original header. This requirement is to ensure that source compatibility is retained.
 
Finally, if you are deprecating a function so that you can change the name of the function, please use the method described above under "Replacing functions", so that projects which use APR can retain binary compatibility.
Note that all deprecated functions will be removed at the next major version bump.
1.2.2.3主版本號策略
下面的任何一種變化都將可能導致主版本號的變化:
1)、常量的移除或者更改
2)、函數移除或者作為
3)、fold together macro-ized function replacements
1.2.3版本檢查
由于APR嚴格的版本控制策略,使得應用程序在使用APR庫之前必須能夠檢測使用的APR庫的版本號。APR答應在編譯以及使用APR的時候檢測它的版本號。
1.2.3.1 編譯時版本檢查
Libraries should make their version number available as compile-time constants. For example:
#define FOO_MAJOR_VERSION 1
#define FOO_MINOR_VERSION 4
#define FOO_PATCH_VERSION 0
The above symbols are the minimum required for this specification.
An application that desires, at compile-time, to decide on whether and how to use a particular library feature needs to only check two values: the major and the minor version. Since, by definition, there are no API changes across patch versions, that symbol can be safely ignored. Note that any kind of a check for a minimum version will then pin that application to at least that version. The application's installation mechanism should then ensure that that minimal version has been installed (for example, using RPM dependency checks).

If the feature changes across minor versions are source compatible, but are (say) simply different choices of values to pass into the library, then an application can support a wider variety of installed libraries if it avoids compile-time checks.
1.2.3.2 執行時版本檢查
A library meeting this specification should support a way for an application to determine the library's version at run-time. This will usually be emboded as a simple function which returns the MAJOR, MINOR, and PATCH triplet in some form.
Run-time checks are preferable in all cases. This type of check enables an application to run against a wider variety of minor releases of a library (the application is "less coupled" to a particular library release). Of course, if an application requires a function that was introduced in a later, minor release, then the application will require that, at least, that release is installed on the target system.
Run-time checks are particurly important if the application is trying to determine if the library has a particular bug that may need to be worked around, but has been fixed in a later release. If the bug is fixed in a patch release, then the only avenue for an application is to perform a runtime check. This is because an application cannot require a specific patch level of the library to be installed -- those libraries are perfectly forward and backwards compatible, and the administrator is free to choose any patch release, knowing that all applications will continue to function properly. If the bug was fixed in a minor release, then it is possible to use a compile-time check, but that would create a tighter coupling to the library.
1.2.3.3 版本API
與前面的版本規則定義一致,APR中定義了數據結構apr_version_t來描述版本規則:
typedef struct {
    int major;      /**< major number */
    int minor;      /**< minor number */
    int patch;      /**< patch number */
    int is_dev;     /**< is development (1 or 0) */
} apr_version_t;
major是當前APR版本的主版本號,minor則是次版本號,patch對應的則是APR的補丁號。es_dev則描述了當前APR庫的狀態:開發版還是發行版,分別對應1和0。
一旦定義了apr_version_t結構,APR就將使用它作為基本的版本控制單位。APR中提供了函數apr_version和apr_version_string分別設置和返回APR的版本。
APR_DECLARE(void) apr_version(apr_version_t *pvsn)
{
    pvsn->major = APR_MAJOR_VERSION;
    pvsn->minor = APR_MINOR_VERSION;
    pvsn->patch = APR_PATCH_VERSION;
#ifdef APR_IS_DEV_VERSION
    pvsn->is_dev = 1;

#else
    pvsn->is_dev = 0;
#endif
}
apr_version函數僅僅就是設置apr_version_t結構中的各個成員。對于每一個APR版本,APR都會將當前的版本號分別用三個常量定義在version.h中,比如,假如版本號是2.2.0,則常量定義應該如下:
#define APR_MAJOR_VERSION       2
#define APR_MINOR_VERSION       2
#define APR_PATCH_VERSION       0
apr_version_string函數僅僅是返回APR_VERSION_STRING宏,該宏定義為:
#define APR_VERSION_STRING /
     APR_STRINGIFY(APR_MAJOR_VERSION) "." /
     APR_STRINGIFY(APR_MINOR_VERSION) "." /
     APR_STRINGIFY(APR_PATCH_VERSION) /
     APR_IS_DEV_STRING
APR_STRINGIFY用于將給定的數值轉換為字符串,因此APR_VERSION_STRING宏就是無非將APR_MAJOR_VERSION,APR_MINOR_VERSION,APR_PATCH_VERSION分別轉換為字符串,再用"."連接起來,最后的形式應該為“2.2.0”。
盡管一般情況下,APR的版本號是“x.x.x”的格式,不過在Window的資源文件.rc中通常是“x,x,x”格式,因此APR中也提供了APR_VERSION_STRING_CSV來提供這種格式的版本號:
#define APR_VERSION_STRING_CSV APR_MAJOR_VERSION ##, /
                             ##APR_MINOR_VERSION ##, /
                             ##APR_PATCH_VERSION
##宏用于將變量與特定字符進行連接形成新的字符串。在后面的部分,我們會不斷看到它的用法。
在一些情況下,應用程序需要使用的APR版本達到一定的版本號,為此,APR中提供了APR_VERSION_AT_LEAST宏用以檢測給定的APR庫是否達到給定的版本要求:
#define APR_VERSION_AT_LEAST(major,minor,patch)                    /
(((major) < APR_MAJOR_VERSION)                                     /
  ((major) == APR_MAJOR_VERSION && (minor) < APR_MINOR_VERSION) /
  ((major) == APR_MAJOR_VERSION && (minor) == APR_MINOR_VERSION && (patch) <= APR_PATCH_VERSION))
假如我們希望當前使用的APR庫的版本不的低于”1.2.0”,那么我們就使用使用APR_VERSION_AT_LEAST(1,2,0)對當前的APR庫版本進行檢查。


關于作者
張中慶,目前主要的研究方向是嵌入式瀏覽器,移動中間件以及大規模服務器設計。目前正在進行Apache的源代碼分析,計劃出版《Apache源代碼全景分析》上下冊。Apache系列文章為本書的草案部分,對Apache感愛好的朋友可以通過flydish1234 at sina.com.cn與之聯系!

假如你覺得本文不錯,請點擊文后的“推薦本文”鏈接??!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产99久久精品一区二区永久免费| 国产精品视频区| 久久精品成人欧美大片古装| 伊人激情综合网| 大胆欧美人体视频| 久久色免费在线视频| 久久久久久999| 亚洲女同性videos| 日本精品性网站在线观看| 福利一区福利二区微拍刺激| 国产在线精品自拍| 永久免费看mv网站入口亚洲| 欧美在线观看日本一区| 国产在线观看不卡| 亚洲高清一区二| 国模视频一区二区| 欧美日韩精品在线| 日韩免费观看av| 欧美激情一区二区久久久| 国产亚洲成精品久久| 久久久日本电影| 在线播放日韩精品| 亚洲欧美精品中文字幕在线| 欧美国产视频一区二区| 日韩在线视频免费观看高清中文| 国产精品人成电影| 精品亚洲va在线va天堂资源站| 日韩精品视频中文在线观看| 国产精品福利在线| 91九色单男在线观看| 永久免费精品影视网站| 亚洲小视频在线| 久久久久久国产精品久久| 日韩精品高清在线观看| 最近中文字幕2019免费| 成人免费福利视频| 亚洲成人精品久久久| 亚洲一区二区中文字幕| 久久久久九九九九| 狠狠躁18三区二区一区| 成人性生交大片免费看小说| 国内外成人免费激情在线视频| 亚洲欧美激情在线视频| 久久91精品国产91久久跳| 性欧美视频videos6一9| 欧美xxxx综合视频| 国产999精品视频| 91亚洲一区精品| 国产精品99导航| 一夜七次郎国产精品亚洲| 日韩av免费一区| 日韩欧美中文字幕在线观看| 国产精品美女久久久久av超清| 国产免费一区二区三区在线能观看| 成人一区二区电影| 在线观看日韩av| 亚洲大尺度美女在线| 欧美精品激情视频| 97婷婷大伊香蕉精品视频| 欧美日韩国产精品一区二区不卡中文| 亚洲无限av看| 欧美三级免费观看| 亚洲国产精品yw在线观看| 中文字幕精品在线视频| 亚洲一区二区久久久| 日韩欧美亚洲成人| 欧美中文字幕在线播放| 亚洲男人第一av网站| 亚洲一区二区免费在线| 色综合五月天导航| 色老头一区二区三区在线观看| 精品国内自产拍在线观看| 超碰97人人做人人爱少妇| 国产91精品在线播放| 国产精品高清在线观看| 午夜精品久久久久久久久久久久久| 欧美日本在线视频中文字字幕| 国产精品极品美女粉嫩高清在线| 国产91对白在线播放| 日韩在线视频中文字幕| 久久不射热爱视频精品| 91精品国产综合久久久久久久久| 亚洲国产精品悠悠久久琪琪| 国产精品激情av电影在线观看| 国产精品欧美日韩一区二区| 欧美性猛交xxxx乱大交极品| 成人女保姆的销魂服务| 高清欧美性猛交xxxx黑人猛交| 亚洲第一综合天堂另类专| 久久天天躁狠狠躁老女人| 欧美精品九九久久| 日韩欧美中文字幕在线观看| 亚洲美女性视频| 久久国产精品影片| 亚洲日本中文字幕免费在线不卡| 国产最新精品视频| 亚洲人在线视频| 热99在线视频| 欧美国产日韩一区二区三区| 亚洲裸体xxxx| 国产精品久久久久久久久久久新郎| 青青草原成人在线视频| 国产精品久久一| 久久婷婷国产麻豆91天堂| 精品色蜜蜜精品视频在线观看| 成人观看高清在线观看免费| 亚洲精品一区二区在线| 亚洲国产精品专区久久| 亚洲区bt下载| 午夜精品视频网站| 中国日韩欧美久久久久久久久| 国产精品福利在线| 国产精品视频一区二区三区四| 成人一区二区电影| 91成人精品网站| 亚洲综合在线中文字幕| 亚洲三级av在线| 久久久久久久91| 国产香蕉97碰碰久久人人| 亚洲精品国产精品国产自| 在线观看久久久久久| 亚洲xxxx妇黄裸体| 久久国产精品久久久久| 97色在线播放视频| 亚洲精品国产精品久久清纯直播| 欧美电影免费观看大全| 欧洲亚洲在线视频| 一本一本久久a久久精品牛牛影视| 亚洲qvod图片区电影| 亚洲国产成人爱av在线播放| 日韩在线播放视频| 揄拍成人国产精品视频| 亚洲激情久久久| 久久成年人免费电影| 国产精品久久久久久久app| 一区二区亚洲欧洲国产日韩| 国产91在线播放九色快色| 欧美性受xxxx黑人猛交| 亚洲一区二区在线播放| 欧美性xxxx18| 国产精品99久久久久久人| 欧美性猛交xxxx| 亚洲综合小说区| 亚洲国产精品va在线看黑人动漫| 97精品欧美一区二区三区| 欧美电影免费观看网站| 亚洲精品美女在线观看| 久久激情视频免费观看| 亚洲国产高清自拍| 中文字幕免费精品一区高清| 国产精品爽爽爽| 精品久久久久久中文字幕大豆网| 97在线观看免费高清| 成人欧美一区二区三区黑人孕妇| 久久久999精品| 欧美大学生性色视频| 亚洲黄色av网站| 91精品国产777在线观看| 亚洲高清av在线| 91精品久久久久久久久久入口| 日本久久久久亚洲中字幕| 日韩电视剧免费观看网站| 日韩欧美亚洲综合| 欧美久久久精品|