中文字幕日韩一区二区_国产一区二区av_国产毛片av_久久久久国产一区_色婷婷电影_国产一区二区精品

PHP下通過系統(tǒng)信號(hào)量加鎖方式獲取遞增序列ID

在網(wǎng)上搜了搜,有兩個(gè)辦法但都不太好:一個(gè)是簡(jiǎn)單的以進(jìn)程ID+時(shí)間戳,或進(jìn)程ID+隨機(jī)數(shù)來產(chǎn)生近似的唯一ID,雖簡(jiǎn)單但對(duì)于追求“完美”的我不愿這樣湊合,再說Apache2以后進(jìn)程會(huì)維持相當(dāng)長(zhǎng)得時(shí)間,生成的ID發(fā)生碰撞的幾率還是比較大的;第二個(gè)思路是通過Mysql的自增字段,這個(gè)就更不能考慮了,效率低不說,我的設(shè)計(jì)里壓根就沒數(shù)據(jù)庫。
遞增ID的獲取是個(gè)過程:
1. 從全局某個(gè)存儲(chǔ)中讀取ID
2. 給ID加1
3. 將ID重新存入全局存儲(chǔ)
在多進(jìn)程或線程的程序中需要將上述3步作為單步的原子操作,才能保證ID的唯一。
Java中很好解決,這是因?yàn)?a href=/itjie/Javajishu/ target=_blank class=infotextkey>Java程序大多以多線程方式運(yùn)行,每個(gè)線程都能共享Java進(jìn)程中的變量,并能方便的加線程鎖控制線程的運(yùn)轉(zhuǎn)同步。在php中ID全局存儲(chǔ)沒問題,可以放在session中,大不了放在文件中,但進(jìn)程間同步就是問題了。
實(shí)際上進(jìn)程調(diào)度、管理是操作系統(tǒng)內(nèi)核必須實(shí)現(xiàn)的功能,今天介紹的信號(hào)量(也稱為信號(hào)燈)就是在Unix/Linux上解決進(jìn)程同步的一項(xiàng)技術(shù)。
信號(hào)燈原是用在鐵路上的管理機(jī)制,我們今天看到的鐵路大多是雙線并行,但有的路段受山勢(shì)、地形影響只有單條鐵軌,必須保證同一時(shí)間只能有一列火車運(yùn)行通過這些路段。早先鐵路上就是用信號(hào)燈來管理的:沒有火車經(jīng)過時(shí),信號(hào)等處于閑置狀態(tài),一旦有火車進(jìn)入此路段,信號(hào)燈即變?yōu)樵谟脿顟B(tài),其他的火車經(jīng)過時(shí)就需要等待,等待先前的火車駛出路段信號(hào)等變?yōu)殚e置后,才能進(jìn)入此路段,一旦又有火車進(jìn)入,信號(hào)燈又變?yōu)榉泵?.....,以此來保障鐵路運(yùn)行的安全暢通。
Unix系統(tǒng)就像鐵路管理局控制信號(hào)燈一樣管理控制信號(hào)量的狀態(tài),因此也可以這樣說信號(hào)量是由內(nèi)核管理的,信號(hào)量不僅能控制進(jìn)程間的同步,同樣可以控制線程間的同步。
信號(hào)量屬于系統(tǒng)進(jìn)程間通訊技術(shù)(IPC),今天我們只從php角度介紹信號(hào)量的使用,有關(guān)IPC的技術(shù)細(xì)節(jié)可參考Stevens的權(quán)威著作《UNIX網(wǎng)絡(luò)編程第二卷 進(jìn)程間通信》。
先看最終的代碼:
復(fù)制代碼 代碼如下:
<?php
// ---------------------------------------------------
// 遞增序列號(hào)ID(1~1000000000)
//
// ID存儲(chǔ)在共享內(nèi)存中(shared memory),通過信號(hào)燈(semaphore)同步
// ---------------------------------------------------
$IPC_KEY = 0x1234; //System V IPC KEY
$SEQ_KEY = "SEQ"; //共享內(nèi)存中存儲(chǔ)序列號(hào)ID的KEY
//創(chuàng)建或獲得一個(gè)現(xiàn)有的,以"1234"為KEY的信號(hào)量
$sem_id = sem_get($IPC_KEY);
//創(chuàng)建或關(guān)聯(lián)一個(gè)現(xiàn)有的,以"1234"為KEY的共享內(nèi)存
$shm_id = shm_attach($IPC_KEY, 64);
//占有信號(hào)量,相當(dāng)于上鎖,同一時(shí)間內(nèi)只有一個(gè)流程運(yùn)行此段代碼
sem_acquire($sem_id);
//從共享內(nèi)存中獲得序列號(hào)ID
$id = @shm_get_var($shm_id, $SEQ_KEY);
if ($id == NULL || $id >= 1000000000)
{
$id = 1;
}
else
{
$id++;
}
//將"++"后的ID寫入共享內(nèi)存
shm_put_var($shm_id, $SEQ_KEY, $id);
//釋放信號(hào)量,相當(dāng)于解鎖
sem_release($sem_id);
//關(guān)閉共享內(nèi)存關(guān)聯(lián)
shm_detach($shm_id);
echo "序列號(hào)ID:{$id}";
?>

009行,定義了一個(gè)16進(jìn)制的整形KEY,在php中只支持System V的IPC機(jī)制,需要通過一個(gè)KEY關(guān)聯(lián)到指定的資源(消息隊(duì)列、信號(hào)量、共享內(nèi)存)。
010 行,定義了一個(gè)在共享內(nèi)存中存儲(chǔ)遞增ID的KEY,這是php對(duì)System V共享內(nèi)存的閑置:需要通過類似hashtable的KEY-VALUE方式存儲(chǔ)變量。在上面的代碼中使用共享內(nèi)存做ID的存儲(chǔ)容器,也可以換為 Session、文件等其他機(jī)制,本文重點(diǎn)是信號(hào)量,有關(guān)共享內(nèi)存的知識(shí)以后在講(別忘了前面推薦的那本書)。
013行,獲得系統(tǒng)中的以1234為KEY的信號(hào)量,如果系統(tǒng)中沒有就創(chuàng)建一個(gè)。
015行,同13行相似,獲得系統(tǒng)中的以1234為KEY的共享內(nèi)存,如果系統(tǒng)中沒有就創(chuàng)建一個(gè),第二個(gè)參數(shù)64表示創(chuàng)建64bytes大小的共享內(nèi)存。
018~034 行,同步代碼區(qū),當(dāng)一個(gè)進(jìn)程或線程執(zhí)行sem_acquire函數(shù)占有了信號(hào)量,到它調(diào)用sem_release函數(shù)釋放信號(hào)量的過程內(nèi),其他進(jìn)程或線程執(zhí)行到sem_acquire會(huì)阻塞。021行從共享內(nèi)存中獲得ID,函數(shù)shm_get_var前綴"@"是為了屏蔽出錯(cuò)信息(第一次執(zhí)行時(shí),共享內(nèi)存中并沒有以"SEQ"為KEY的數(shù)據(jù),會(huì)在頁面上打印警告信息)。
其他語句非常簡(jiǎn)單,不需多講。
程序編好后,訪問這個(gè)php頁面,會(huì)遞增的輸出數(shù)字。
我們可以通過系統(tǒng)命令ipcs查看在程序創(chuàng)建的信號(hào)量和共享內(nèi)存:
$ ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00001234 1212443 www-data 666 64 0
------ Semaphore Arrays --------
key semid owner perms nsems
0x00001234 163841 www-data 666 3
------ Message Queues --------
key msqid owner perms used-bytes messages
前兩段分別是共享內(nèi)存和信號(hào)量,0x00001234既是我們創(chuàng)建的KEY。
也可以通過命令ipcrm刪除:
$ ipcrm -M 0x00001234 #刪除共享內(nèi)存
$ ipcrm -S 0x00001234 #刪除信號(hào)量
---------------------------------------------
php手冊(cè)中關(guān)于IPC的資料非常少,這點(diǎn)也不難想象,Stevens已經(jīng)在十幾年前講得透透的東東,在php中只是包裝了一下,還有多少必要去深入說明呢?
文本只是借著ID說了說信號(hào)量的使用,如果您有更簡(jiǎn)單的生成自增ID的辦法,還望賜教。
可能有朋友還想了解信號(hào)量的執(zhí)行效率,我這里用一句過時(shí)的流行語總結(jié): 相當(dāng)?shù)目臁?

php技術(shù)PHP下通過系統(tǒng)信號(hào)量加鎖方式獲取遞增序列ID,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: www.亚洲一区| 国产三级精品三级在线观看四季网 | 99精品国自产在线观看 | 最新免费视频 | 久久久久黄 | 午夜合集 | 神马福利 | 亚洲精品一区二区三区在线 | 亚洲日韩中文字幕 | 中文字幕亚洲一区二区va在线 | 国产乱码精品一区二区三区中文 | 久久天堂网 | 综合九九 | 欧美精品在线观看 | 国产精品区二区三区日本 | 亚洲欧美中文日韩在线v日本 | 欧美成人一区二区三区片免费 | 日韩欧美三级 | 国产精品免费大片 | www.婷婷| 日韩亚洲欧美一区 | 不卡一二区 | 九九九视频在线 | 国产成人精品一区二区三区 | 一区二区三区四区视频 | 国产精品一区二区久久久久 | 日本一区二区三区四区 | 国产高清免费视频 | 日本午夜免费福利视频 | 在线欧美一区 | 久久久久久久久久久久91 | 日韩一区二区不卡 | 黑人精品xxx一区一二区 | 日韩在线免费 | 精品久久久久久久久久久久久久 | 国产91丝袜 | 成人区一区二区三区 | 精品在线观看入口 | 国产www.| 欧美国产视频一区二区 | 国产免费一区二区三区 |