亚洲综合原千岁中文字幕_国产精品99久久久久久久vr_无码人妻aⅴ一区二区三区浪潮_成人h动漫精品一区二区三

主頁(yè) > 知識(shí)庫(kù) > 淺談并發(fā)處理PHP進(jìn)程間通信之外部介質(zhì)

淺談并發(fā)處理PHP進(jìn)程間通信之外部介質(zhì)

熱門標(biāo)簽:常州地圖標(biāo)注服務(wù)商 福州人工外呼系統(tǒng)哪家強(qiáng) 安裝電銷外呼系統(tǒng) 新河科技智能外呼系統(tǒng)怎么樣 釘釘打卡地圖標(biāo)注 衡水外呼系統(tǒng)平臺(tái) 百度商鋪地圖標(biāo)注 地圖標(biāo)注平臺(tái)怎么給錢注冊(cè) 注冊(cè)400電話申請(qǐng)

進(jìn)程間通信

進(jìn)程間通信,指至少兩個(gè)進(jìn)程或線程間傳送數(shù)據(jù)或信號(hào)的一些技術(shù)或方法。進(jìn)程是計(jì)算機(jī)系統(tǒng)分配資源的最小單位(嚴(yán)格說(shuō)來(lái)是線程)。每個(gè)進(jìn)程都有自己的一部分獨(dú)立的系統(tǒng)資源,彼此是隔離的。為了能使不同的進(jìn)程互相訪問(wèn)資源并進(jìn)行協(xié)調(diào)工作,才有了進(jìn)程間通信。

根據(jù)定義可知,要進(jìn)行進(jìn)程間通信,我們需要解決兩個(gè)問(wèn)題:

  • 互相訪問(wèn):消息傳輸和暫時(shí)存儲(chǔ)介質(zhì)選擇問(wèn)題;
  • 協(xié)調(diào)工作:消息的存取沖突問(wèn)題;

文章介紹的中心就是圍繞著這么兩點(diǎn)來(lái)說(shuō)的, 為了更使文章更簡(jiǎn)明,這邊以之前在公司做的一個(gè)需求為例:

需要一個(gè)循環(huán)ID生成器,循環(huán)生成從 Min 到 Max 的數(shù)字ID,在ID遞增到 Max 后,返回到 Min 重新開(kāi)始遞增;必須能保證多個(gè)進(jìn)程并發(fā)請(qǐng)求時(shí)生成的ID不同。

此需求要解決的問(wèn)題恰好為我們要解決的進(jìn)程間通信需要解決的兩個(gè)問(wèn)題:

  • 需要一個(gè)消息傳輸通道來(lái)傳輸和存儲(chǔ)當(dāng)前的遞增值。這個(gè)比較容易解決,我們常用的文件、數(shù)據(jù)庫(kù)、session、緩存等都能做到。
  • 需要解決多進(jìn)程同時(shí)訪問(wèn)生成器生成相同ID的問(wèn)題。要滿足這個(gè)需要就必須要用到鎖了,而且為了保證多個(gè)進(jìn)程讀取的數(shù)據(jù)是不同的,需要互斥鎖,另外為了能保證調(diào)用成功率,鎖的獲取最好能實(shí)現(xiàn)自旋。

本文通過(guò)此需求的不同實(shí)現(xiàn),來(lái)介紹通過(guò)外部介質(zhì)進(jìn)行的進(jìn)程間通信的方式。另外,不只PHP語(yǔ)言,其他語(yǔ)言也能使用這些方法。

文件

flock

文件是最基本的存儲(chǔ)介質(zhì),它當(dāng)然可以作為消息的傳輸通道來(lái)使用。文件的存取各種語(yǔ)言都有各自的多種方案,問(wèn)題點(diǎn)是多進(jìn)程并發(fā)時(shí)的沖突問(wèn)題。

解決存取沖突問(wèn)題我們使用PHP的flock()函數(shù):

bool flock ( resource $handle , int $operation [, int $wouldblock ] )

$handler 是 使用fopen($path_to_file)獲取到的文件句柄;

$operation 是 對(duì)文件加鎖的方式,有以下值可選:

LOCK_SH (獲取共享鎖) / LOCK_EX (獲取互斥鎖) / LOCK_UN (解鎖)

這里我們選用互斥鎖,一個(gè)進(jìn)程獲取到互斥鎖后,其他進(jìn)程在嘗試獲取鎖會(huì)被阻塞,直到鎖被釋放,即實(shí)現(xiàn)了自旋;

此外,還有一個(gè)參數(shù) LOCK_NB,flock 在獲取不到鎖時(shí),默認(rèn)會(huì)阻塞住直到鎖被其他進(jìn)程釋放,傳入 LOCK_NB 與 LOCK_SH 或 LOCK_EX 進(jìn)行或運(yùn)算結(jié)果(LOCK_EX | LOCK_NB),flock 在鎖被其他進(jìn)程占有時(shí),不會(huì)阻塞,而是直接返回 false,這里僅作介紹,我們并不使用它。

$wouldblock 參數(shù)是一個(gè)引用值,在獲取不到鎖,且不阻塞模式時(shí),$wouldblock 會(huì)被設(shè)置為 true;(手冊(cè)中說(shuō)阻塞時(shí)才會(huì)被設(shè)置為 true。其實(shí)我也奇怪這個(gè)變量名的。不知道是不是 bug,我的PHP版本是 5.4.5,有知道的煩請(qǐng)解惑)

代碼實(shí)現(xiàn)

下面是循環(huán)ID生成器代碼,說(shuō)明在注釋中:

function getCycleIdFromFile($max, $min = 0) {
    $handler = fopen('/tmp/cycle_id_generator.txt', 'c+');
    if (!flock($handler, LOCK_EX)) {
        throw new Exception('error_get_file_lock!');
    }
    
    $cycle_id = trim(fread($handler, 9));
    $cycle_id++;

    if ($cycle_id > $max) {
        $cycle_id = $min;
    }

    // 文件指針?lè)祷氐轿募^,并向文件內(nèi)寫入新的cycle_id
    rewind($handler);
    fwrite($handler, $cycle_id);

    // 多寫入一些空格為了防止數(shù)值升到多位后,突然置為少位后面的數(shù)字仍保留
    fwrite($handler, str_repeat(' ', 9));

    flock($handler, LOCK_UN);

    return $cycle_id;
}

mysql

select for update

我們常用的 mysql 也可以被當(dāng)作中間介質(zhì)來(lái)實(shí)現(xiàn)進(jìn)程間的通信,我們規(guī)定好某一個(gè)數(shù)據(jù)表內(nèi)的某一行數(shù)據(jù)作為消息交換的中轉(zhuǎn)站,使用 mysql 自帶的鎖來(lái)協(xié)調(diào)多個(gè)進(jìn)程的存取沖突。

事務(wù)的設(shè)計(jì)目的就是為了解決多進(jìn)程并發(fā)查詢時(shí)數(shù)據(jù)沖突的問(wèn)題,可是我們常用的事務(wù)只能保證數(shù)據(jù)沖突時(shí)會(huì)被回滾,數(shù)據(jù)不會(huì)出現(xiàn)錯(cuò)誤,并不能實(shí)現(xiàn)請(qǐng)求的并行化。對(duì)一些數(shù)據(jù)沖突回滾的請(qǐng)求,需要我們?cè)谕鈱犹砑舆壿嬛卦嚒?/p>

這里介紹 mysql 的一種語(yǔ)法: select for update,會(huì)給固定數(shù)據(jù)加上互斥鎖,且另一個(gè)請(qǐng)求在獲取鎖失敗時(shí),會(huì)阻塞至獲取鎖成功,mysql 幫我們實(shí)現(xiàn)了自旋;

用法如下:

1.關(guān)閉 mysql 的自動(dòng)提交,自動(dòng)提交默認(rèn)打開(kāi),除非使用 transition 語(yǔ)句顯示開(kāi)啟事務(wù),默認(rèn)會(huì)將每一條 sql 作為一個(gè)事務(wù)直接提交執(zhí)行,這里關(guān)閉。 set autocommit=0;

2.使用select for update 語(yǔ)句給數(shù)據(jù)添加互斥鎖。注意:需求 mysql 的 innodb 引擎支持;

3.進(jìn)行數(shù)據(jù)更新和處理操作;

4.主動(dòng)提交事務(wù),并將 自動(dòng)提交恢復(fù);commit; set autocommit=1;

代碼實(shí)現(xiàn)

然后是代碼實(shí)現(xiàn):

// 數(shù)據(jù)庫(kù)連接實(shí)現(xiàn)各有不同,demo 可以自己修改一下。
function getCycleIdFromMysql($max, $min = 0){
    Db::db()->execute('set autocommit = 0');
    $res = Db::db()->qsqlone('SELECT cycle_id FROM cycle_id_generator WHERE id = 1 FOR UPDATE');

    $cycle_id = $res['cycle_id'] + 1;
    if($cycle_id > $max){
        $cycle_id = $min;
    }

    Db::db()->execute("UPDATE cycle_id_generator SET cycle_id = {$cycle_id} WHERE id = 1");

    Db::db()->execute('commit');
    Db::db()->execute('set autocommit = 1');

    return $cycle_id;
}

redis

incr

redis 是我們常用的緩存服務(wù)器,由于其使用內(nèi)存存儲(chǔ)數(shù)據(jù),性能很高。我們使用一個(gè)固定的普通鍵來(lái)作為消息中轉(zhuǎn)站,然后利用其incr命令的原子性和其執(zhí)行結(jié)果(遞增后的值),實(shí)現(xiàn) cycle_id 的遞增。

incr(key) 若 key 不存在,redis 會(huì)先將值設(shè)置為0,然后執(zhí)行遞增操作;

遞增沒(méi)有問(wèn)題,可是我們還有個(gè)需求是在要其值達(dá)到 max 時(shí),再將其置為 min,這時(shí)就可能會(huì)出現(xiàn)進(jìn)程A在更新值為 min 時(shí),另一個(gè)進(jìn)程B也檢測(cè)到值大于了 max,然后將值置為 min,可是這時(shí)的值已經(jīng)不是 max,即發(fā)生了值重復(fù)更新,那么返回的值必然會(huì)有重復(fù);

這時(shí),我們就需要自己來(lái)實(shí)現(xiàn)鎖了。

SETNX

redis 的 SETNX 命令檢測(cè)某一個(gè) key 是否存在,若不存在,則將 key 的值設(shè)置為 value,并返回結(jié)果1; 若 key 已存在,則設(shè)置失敗,返回值0。

SETNX key value

它能實(shí)現(xiàn)鎖是因?yàn)樗且粋€(gè)原子命令,即 檢測(cè) key 是否存在和設(shè)置 key 值在一個(gè)事務(wù)內(nèi),不會(huì)出現(xiàn)同時(shí)兩個(gè)進(jìn)程都檢測(cè)到 key 不存在,然后同時(shí)去設(shè)置 key 的情況。

我們以另一個(gè)值的存在與否,來(lái)表示 cycle_id 是否正在被另一個(gè)進(jìn)程修改。

代碼實(shí)現(xiàn)

 function getCycleIdFromRedis($max, $min = 0) {
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    $key_id = 'cycle_id_generator';

    $cycle_id = $redis->incr($key_id);
    
    if ($cycle_id > $max) {
        // 設(shè)置"鎖鍵"的結(jié)果 = 獲取互斥結(jié)果
        $key_lock = 'cycle_id_lock';
        if (!$redis->setnx($key_lock, 1)) {
            return null;
        }

        $cycle_id = $min;
        $redis->set($key_id, $cycle_id);

        // 最后別忘記釋放互斥鎖
        $redis->delete($key_lock);
    }

    $redis->close();

    return $cycle_id;
}

注意:由于 redis 里沒(méi)有能實(shí)現(xiàn)自旋鎖的命令,如果需求最高的獲取成功率,我們?cè)跈z測(cè)到 cycle_id 已經(jīng)是最大值,且試圖修改獲取鎖失敗時(shí),退出重試,在外層進(jìn)行重試。

function getCycleId($max, $min = 0) {
    $cycle_id = getCycleIdFromRedis($max, $min);
    if (!is_null($cycle_id)) {
        return $cycle_id;
    }
    // 稍微等待下正在更改的進(jìn)程
    usleep(500);
    // 這里使用遞歸,直至獲取成功  并發(fā)很高,cycle_id重置很頻繁時(shí)慎用.
    return getCycleId($max, $min);
}

優(yōu)化

審查代碼我們會(huì)發(fā)現(xiàn),如果 max-min 的值很小的話,redis 會(huì)需要經(jīng)常重置 key 的值,也就經(jīng)常需要加鎖,重試也就很多。這里,我提供一個(gè)優(yōu)化方法:

我們將其 max 設(shè)置為一個(gè)很大的值(要能被 max-min 整除),返回值時(shí)稍做處理,返回 $current % ($max - $min) + $min;。這樣,key 需要遞增到一個(gè)很大的值才會(huì)被重置,加鎖邏輯和外層邏輯會(huì)很少執(zhí)行到,達(dá)到提升效率的目的。

總結(jié)

這里簡(jiǎn)單的評(píng)價(jià)一下上面所說(shuō)的三種方法:

性能上沒(méi)有測(cè)試,而且 redis 的性能跟 ID 的大小差值相關(guān),不過(guò)猜測(cè)在ID大小差值大的情況下 redis 應(yīng)該更好一點(diǎn)。

代碼上非常直觀,使用 mysql 非常簡(jiǎn)潔,而且 redis 要自己實(shí)現(xiàn)自旋,比較惡心。

實(shí)現(xiàn)上,當(dāng)然是文件最為方便,無(wú)任何添加。

以上就是淺談并發(fā)處理PHP進(jìn)程間通信之外部介質(zhì)的詳細(xì)內(nèi)容,更多關(guān)于并發(fā)處理PHP進(jìn)程間通信之外部介質(zhì)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • PHP下用Swoole實(shí)現(xiàn)Actor并發(fā)模型的方法
  • 淺談并發(fā)處理PHP進(jìn)程間通信之System V IPC
  • PHP+Redis鏈表解決高并發(fā)下商品超賣問(wèn)題(實(shí)現(xiàn)原理及步驟)
  • 詳解PHP中curl_multi并發(fā)的實(shí)現(xiàn)
  • php多進(jìn)程并發(fā)編程防止出現(xiàn)僵尸進(jìn)程的方法分析
  • PHP高并發(fā)和大流量解決方案整理
  • PHP 并發(fā)場(chǎng)景的幾種解決方案
  • php多進(jìn)程模擬并發(fā)事務(wù)產(chǎn)生的問(wèn)題小結(jié)
  • 淺談Swoole并發(fā)編程的魅力

標(biāo)簽:鶴崗 遼陽(yáng) 鷹潭 六安 柳州 克拉瑪依 唐山 白城

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《淺談并發(fā)處理PHP進(jìn)程間通信之外部介質(zhì)》,本文關(guān)鍵詞  淺談,并發(fā),處理,PHP,進(jìn)程,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《淺談并發(fā)處理PHP進(jìn)程間通信之外部介質(zhì)》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于淺談并發(fā)處理PHP進(jìn)程間通信之外部介質(zhì)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    成人av在线播放| 国产精品1024在线永久免费| 日本特黄特色aaa大片免费| 国产精品1024在线永久免费| 久久久久久久男人的天堂| 91麻豆精品国产片在线观看| 久久福利影视| 久久99这里只有精品国产| 欧美大片aaaa一级毛片| 91麻豆tv| 欧美a级v片不卡在线观看| a级黄色毛片免费播放视频| 精品视频在线观看一区二区三区| 国产不卡在线看| 久久精品人人做人人爽97| 国产a毛片| 一级毛片看真人在线视频| 四虎影视库| 精品在线免费播放| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 成人在免费观看视频国产| 国产视频在线免费观看| 亚洲第一色在线| 99热精品一区| 精品国产香蕉伊思人在线又爽又黄| 韩国三级香港三级日本三级| 国产一区二区精品在线观看| 91麻豆精品国产片在线观看| 精品视频在线观看免费| 色综合久久久久综合体桃花网| a级黄色毛片免费播放视频| 日韩中文字幕一区二区不卡| 成人免费观看视频| 国产高清在线精品一区a| 91麻豆国产福利精品| 韩国毛片| 日本免费乱人伦在线观看| 国产精品自拍一区| 亚洲 欧美 成人日韩| 国产成人精品影视| 免费国产在线视频| 国产a视频| 亚洲 激情| 尤物视频网站在线观看| 韩国三级视频网站| 国产精品自拍在线观看| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 欧美国产日韩久久久| 欧美一级视频免费| 国产不卡高清| 精品视频在线观看视频免费视频| 国产精品123| 天天做人人爱夜夜爽2020| 精品国产三级a∨在线观看| 九九干| 91麻豆爱豆果冻天美星空| 久久久久久久久综合影视网| 精品视频在线观看视频免费视频| 久久精品道一区二区三区| 一级女性大黄生活片免费| 成人a大片在线观看| 尤物视频网站在线| 国产一级强片在线观看| 欧美a级片视频| 四虎久久影院| 日本在线不卡视频| 韩国三级视频网站| 日韩中文字幕一区| 国产成人精品综合| 韩国三级香港三级日本三级la | 天天做日日干| 国产精品自拍在线观看| 日韩免费片| 欧美日本免费| 韩国三级香港三级日本三级la | 国产福利免费观看| 天天色色网| 免费一级片在线| 黄视频网站免费观看| 欧美一级视频高清片| 四虎影视久久久| 日韩中文字幕在线观看视频| 91麻豆爱豆果冻天美星空| 久久精品免视看国产明星| 亚飞与亚基在线观看| 午夜在线影院| 欧美另类videosbestsex高清| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 91麻豆国产| 久久99这里只有精品国产| 精品视频在线观看一区二区| 欧美18性精品| 一a一级片| 黄视频网站在线观看| 午夜精品国产自在现线拍| 99久久精品国产高清一区二区| 欧美a免费| 精品国产亚一区二区三区| 欧美激情伊人| 亚洲精品久久久中文字| 韩国三级视频网站| 精品国产香蕉伊思人在线又爽又黄| 黄视频网站在线看| 天天做日日爱夜夜爽| 国产韩国精品一区二区三区| 99色视频在线观看| 欧美激情一区二区三区视频| 欧美a级片免费看| 日韩一级黄色片| 色综合久久天天综合观看| 国产国语对白一级毛片| 国产一级生活片| 国产伦久视频免费观看视频| 久久99爰这里有精品国产| 国产一区二区精品久久91| 精品国产一区二区三区久久久蜜臀 | 九九久久国产精品| 国产高清在线精品一区二区| 国产不卡福利| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 欧美a级片免费看| 国产a视频| 午夜在线亚洲男人午在线| 超级乱淫伦动漫| 亚洲女初尝黑人巨高清在线观看| 精品视频在线观看一区二区三区| 欧美激情一区二区三区视频| 国产a视频精品免费观看| 日本免费区| 色综合久久天天综合| 国产伦久视频免费观看 视频| 精品视频免费在线| 青青青草影院| 欧美α片无限看在线观看免费| 九九干| 欧美a级片免费看| 欧美日本二区| 香蕉视频亚洲一级| a级毛片免费全部播放| 日本特黄特色aaa大片免费| 韩国毛片免费| 可以免费看污视频的网站| 国产成人精品影视| 欧美一级视频免费| 色综合久久天天综合观看| 精品国产亚洲一区二区三区| 日本在线不卡视频| 你懂的日韩| 四虎影视库| 四虎久久影院| 精品久久久久久免费影院| 色综合久久天天综合观看| 国产麻豆精品免费视频| 国产一区二区精品| 国产不卡在线看| 日本特黄一级| 亚洲wwwwww| 欧美激情在线精品video| 久久精品免视看国产成人2021| 亚洲女人国产香蕉久久精品| 免费国产一级特黄aa大片在线| 日韩中文字幕一区| 欧美大片毛片aaa免费看| 日韩中文字幕一区| 四虎影视库| 国产一区免费在线观看| 一a一级片| 亚洲 男人 天堂| 国产伦精品一区三区视频| 日韩在线观看免费| 日本免费乱理伦片在线观看2018| 国产韩国精品一区二区三区| 99色视频在线| 午夜欧美成人香蕉剧场| 91麻豆国产| 欧美电影免费| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 久久99欧美| 久久99中文字幕| 国产一级强片在线观看| a级精品九九九大片免费看| 日本免费看视频| 亚洲第一页色| 999精品在线| 可以免费看污视频的网站| 午夜欧美成人香蕉剧场| 国产成人精品综合在线| 日韩在线观看视频网站| 麻豆午夜视频| 精品国产亚洲一区二区三区| 一级女性全黄久久生活片| 国产韩国精品一区二区三区| 国产91精品一区| 日韩一级黄色| 国产不卡在线观看| 国产一级强片在线观看| 国产成人精品综合| 国产麻豆精品免费密入口| 国产高清在线精品一区二区| 国产视频网站在线观看|