电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

PHP編程中的鎖

瀏覽:128日期:2022-09-12 13:11:56

最近看了《理解Linux進(jìn)程》這本開(kāi)源書(shū),鏈接。該書(shū)描述了linux中的進(jìn)程概念,對(duì)鎖和進(jìn)程間通信(IPC)有一些總結(jié)。不過(guò)該書(shū)的描述語(yǔ)言是golang, 平時(shí)用的比較少,就想對(duì)應(yīng)概念找找php中的接口。

文件鎖

全名叫advisory file lock, 書(shū)中有提及。 這類(lèi)鎖比較常見(jiàn),例如 mysql, php-fpm 啟動(dòng)之后都會(huì)有一個(gè)pid文件記錄了進(jìn)程id,這個(gè)文件就是文件鎖。

這個(gè)鎖可以防止重復(fù)運(yùn)行一個(gè)進(jìn)程,例如在使用crontab時(shí),限定每一分鐘執(zhí)行一個(gè)任務(wù),但這個(gè)進(jìn)程運(yùn)行時(shí)間可能超過(guò)一分鐘,如果不用進(jìn)程鎖解決沖突的話(huà)兩個(gè)進(jìn)程一起執(zhí)行就會(huì)有問(wèn)題。

使用PID文件鎖還有一個(gè)好處,方便進(jìn)程向自己發(fā)停止或者重啟信號(hào)。例如重啟php-fpm的命令為

kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`

發(fā)送USR2信號(hào)給pid文件記錄的進(jìn)程,信號(hào)屬于進(jìn)程通信,會(huì)另開(kāi)一個(gè)篇幅。

php的接口為flock,文檔比較詳細(xì)。先看一下定義,bool flock ( resource $handle , int $operation [, int &$wouldblock ] ).

$handle是文件系統(tǒng)指針,是典型地由 fopen() 創(chuàng)建的 resource(資源)。這就意味著使用flock必須打開(kāi)一個(gè)文件。

$operation是操作類(lèi)型。

&$wouldblock如果鎖是阻塞的,那么這個(gè)變量會(huì)設(shè)為1.

需要注意的是,這個(gè)函數(shù)默認(rèn)是阻塞的,如果想非阻塞可以在 operation 加一個(gè) bitmaskLOCK_NB. 接下來(lái)測(cè)試一下。

$pid_file = '/tmp/process.pid';$pid = posix_getpid();$fp = fopen($pid_file, ’w+’);if(flock($fp, LOCK_EX | LOCK_NB)){ echo 'got the lock n'; ftruncate($fp, 0); // truncate file fwrite($fp, $pid); fflush($fp); // flush output before releasing the lock sleep(300); // long running process flock($fp, LOCK_UN); // 釋放鎖定} else { echo 'Cannot get pid lock. The process is already up n';}fclose($fp);

保存為process.php,運(yùn)行php process.php &, 此時(shí)再次運(yùn)行php process.php,就可以看到錯(cuò)誤提示。flock也有共享鎖,LOCK_SH.

互斥鎖和讀寫(xiě)鎖sync模塊中的Mutex

Mutex是一個(gè)組合詞,mutual exclusion。用pecl安裝一下sync模塊,pecl install sync。 文檔中的SyncMutex只有兩個(gè)方法,lock 和 unlock, 我們就直接上代碼測(cè)試吧。沒(méi)有用IDE寫(xiě),所以cs異常丑陋,請(qǐng)無(wú)視。

$mutex = new SyncMutex('UniqueName');for($i=0; $i<2; $i++){ $pid = pcntl_fork(); if($pid <0){die('fork failed'); }elseif ($pid>0){echo 'parent process n'; }else{echo 'child process {$i} is born. n';obtainLock($mutex, $i); }}while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo 'Child $status completedn'; }function obtainLock ($mutex, $i){ echo 'process {$i} is getting the mutex n'; $res = $mutex->lock(200); sleep(1); if (!$res){echo 'process {$i} unable to lock mutex. n'; }else{echo 'process {$i} successfully got the mutex n';$mutex->unlock(); } exit();}

保存為mutex.php, runphp mutex.php, output is

parent process parent process child process 1 is born. process 1 is getting the mutex child process 0 is born. process 0 is getting the mutex process 1 successfully got the mutex Child 0 completedprocess 0 unable to lock mutex. Child 0 completed

這里子進(jìn)程0和1不一定誰(shuí)在前面。但是總有一個(gè)得不到鎖。這里SyncMutex::lock(int $millisecond)的參數(shù)是 millisecond, 代表阻塞的時(shí)長(zhǎng), -1 為無(wú)限阻塞。

sync模塊中的讀寫(xiě)鎖

SyncReaderWriter的方法類(lèi)似,readlock,readunlock,writelock,writeunlock,成對(duì)出現(xiàn)即可,沒(méi)有寫(xiě)測(cè)試代碼,應(yīng)該和Mutex的代碼一致,把鎖替換一下就可以。

sync模塊中的Event

感覺(jué)和golang中的Cond比較像,wait()阻塞,fire()喚醒Event阻塞的一個(gè)進(jìn)程。有一篇好文介紹了Cond, 可以看出Cond就是鎖的一種固定用法。SyncEvent也一樣。php文檔中的例子顯示,fire()方法貌似可以用在web應(yīng)用中。

上測(cè)試代碼

for($i=0; $i<3; $i++){ $pid = pcntl_fork(); if($pid <0){die('fork failed'); }elseif ($pid>0){//echo 'parent process n'; }else{echo 'child process {$i} is born. n';switch ($i) {case 0: wait(); break;case 1: wait(); break;case 2: sleep(1); fire(); break;} }}while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo 'Child $status completedn'; }function wait(){ $event = new SyncEvent('UniqueName'); echo 'before waiting. n'; $event->wait(); echo 'after waiting. n'; exit();}function fire(){ $event = new SyncEvent('UniqueName'); $event->fire(); exit();}

這里故意少寫(xiě)一個(gè)fire(), 所以程序會(huì)阻塞,證明了 fire() 一次只喚醒一個(gè)進(jìn)程。

pthreads模塊

貌似也看到了Mutex, Cond, Pool. 沒(méi)來(lái)得及看,看完再補(bǔ)充。

信號(hào)量sync模塊中的信號(hào)量

SyncSemaphore文檔中顯示,它和Mutex的不同之處,在于Semaphore一次可以被多個(gè)進(jìn)程(或線程)得到,而Mutex一次只能被一個(gè)得到。所以在SyncSemaphore的構(gòu)造函數(shù)中,有一個(gè)參數(shù)指定信號(hào)量可以被多少進(jìn)程得到。public SyncSemaphore::__construct ([ string $name [, integer $initialval [, bool $autounlock ]]] )就是這個(gè)$initialval(initial value)

$lock = new SyncSemaphore('UniqueName', 2);for($i=0; $i<2; $i++){ $pid = pcntl_fork(); if($pid <0){die('fork failed'); }elseif ($pid>0){echo 'parent process n'; }else{echo 'child process {$i} is born. n';obtainLock($lock, $i); }}while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo 'Child $status completedn'; }function obtainLock ($lock, $i){ echo 'process {$i} is getting the lock n'; $res = $lock->lock(200); sleep(1); if (!$res){echo 'process {$i} unable to lock lock. n'; }else{echo 'process {$i} successfully got the lock n';$lock->unlock(); } exit();}

這時(shí)候兩個(gè)進(jìn)程都能得到鎖。

sysvsem模塊中的信號(hào)量

sem_get創(chuàng)建信號(hào)量

sem_remove刪除信號(hào)量(一般不用)

sem_acquire請(qǐng)求得到信號(hào)量

sem_release釋放信號(hào)量。和sem_acquire成對(duì)使用。

$key = ftok(’/tmp’, ’c’);$sem = sem_get($key);for($i=0; $i<2; $i++){ $pid = pcntl_fork(); if($pid <0){die('fork failed'); }elseif ($pid>0){//echo 'parent process n'; }else{echo 'child process {$i} is born. n';obtainLock($sem, $i); }}while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo 'Child $status completedn'; }sem_remove($sem); // finally remove the semfunction obtainLock ($sem, $i){ echo 'process {$i} is getting the sem n'; $res = sem_acquire($sem, true); sleep(1); if (!$res){echo 'process {$i} unable to get sem. n'; }else{echo 'process {$i} successfully got the sem n';sem_release($sem); } exit();}

這里有一個(gè)問(wèn)題,sem_acquire()第二個(gè)參數(shù)$nowait默認(rèn)為false,阻塞。我設(shè)為了true,如果得到鎖失敗,那么后面的sem_release會(huì)報(bào)警告PHP Warning: sem_release(): SysV semaphore 4 (key 0x63000081) is not currently acquired in /home/jason/sysvsem.php on line 33, 所以這里的release操作必須放在得到鎖的情況下執(zhí)行,前面的幾個(gè)例子中沒(méi)有這個(gè)問(wèn)題,沒(méi)得到鎖執(zhí)行release也不會(huì)報(bào)錯(cuò)。當(dāng)然最好還是成對(duì)出現(xiàn),確保得到鎖的情況下再release。

此外,ftok這個(gè)方法的參數(shù)有必要說(shuō)明下,第一個(gè) 必須是existing, accessable的文件, 一般使用項(xiàng)目中的文件,第二個(gè)是單字符字符串。返回一個(gè)int。

輸出為

parent process parent process child process 1 is born. process 1 is getting the mutex child process 0 is born. process 0 is getting the mutex process 1 successfully got the mutex Child 0 completedprocess 0 unable to lock mutex. Child 0 completed

最后,如果文中有錯(cuò)誤的地方,希望大神指出,幫助一下菜鳥(niǎo)進(jìn)步,謝謝各位。

標(biāo)簽: PHP
相關(guān)文章:
主站蜘蛛池模板: 知网论文检测系统入口_论文查重免费查重_中国知网论文查询_学术不端检测系统 | 楼梯定制_楼梯设计施工厂家_楼梯扶手安装制作-北京凌步楼梯 | 欧美日韩国产一区二区三区不_久久久久国产精品无码不卡_亚洲欧洲美洲无码精品AV_精品一区美女视频_日韩黄色性爱一级视频_日本五十路人妻斩_国产99视频免费精品是看4_亚洲中文字幕无码一二三四区_国产小萍萍挤奶喷奶水_亚洲另类精品无码在线一区 | 517瓜水果特产网|一个专注特产好物的网站 | 进口试验机价格-进口生物材料试验机-西安卡夫曼测控技术有限公司 | 环境模拟实验室_液体-气体控温机_气体控温箱_无锡双润冷却科技有限公司 | 油罐车_加油机_加油卷盘_加油机卷盘_罐车人孔盖_各类球阀_海底阀等车用配件厂家-湖北华特专用设备有限公司 | 附着力促进剂-尼龙处理剂-PP处理剂-金属附着力处理剂-东莞市炅盛塑胶科技有限公司 | 制氮设备-变压吸附制氮设备-制氧设备-杭州聚贤气体设备制造有限公司 | 东莞注册公司-代办营业执照-东莞公司注册代理记账-极刻财税 | 酒糟烘干机-豆渣烘干机-薯渣烘干机-糟渣烘干设备厂家-焦作市真节能环保设备科技有限公司 | 小型气象站_车载气象站_便携气象站-山东风途物联网 | 呼末二氧化碳|ETCO2模块采样管_气体干燥管_气体过滤器-湖南纳雄医疗器械有限公司 | 展厅设计-展馆设计-专业企业展厅展馆设计公司-昆明华文创意 | 润滑脂-高温润滑脂-轴承润滑脂-食品级润滑油-索科润滑油脂厂家 | 长江船运_国内海运_内贸船运_大件海运|运输_船舶运输价格_钢材船运_内河运输_风电甲板船_游艇运输_航运货代电话_上海交航船运 | 玻璃钢罐_玻璃钢储罐_盐酸罐厂家-河北华盛节能设备有限公司 | 干洗店加盟_洗衣店加盟_干洗店设备-伊蔻干洗「武汉总部」 | 短信通106短信接口验证码接口群发平台_国际短信接口验证码接口群发平台-速度网络有限公司 | 合肥活动房_安徽活动板房_集成打包箱房厂家-安徽玉强钢结构集成房屋有限公司 | 防爆电机-高压防爆电机-ybx4电动机厂家-河南省南洋防爆电机有限公司 | 郑州宣传片拍摄-TVC广告片拍摄-微电影短视频制作-河南优柿文化传媒有限公司 | 温州中研白癜风专科_温州治疗白癜风_温州治疗白癜风医院哪家好_温州哪里治疗白癜风 | 烟气在线监测系统_烟气在线监测仪_扬尘检测仪_空气质量监测站「山东风途物联网」 | 杜康白酒加盟_杜康酒代理_杜康酒招商加盟官网_杜康酒厂加盟总代理—杜康酒神全国运营中心 | 胀套-锁紧盘-风电锁紧盘-蛇形联轴器「厂家」-瑞安市宝德隆机械配件有限公司 | 户外-组合-幼儿园-不锈钢-儿童-滑滑梯-床-玩具-淘气堡-厂家-价格 | 压接机|高精度压接机|手动压接机|昆明可耐特科技有限公司[官网] 胶泥瓷砖胶,轻质粉刷石膏,嵌缝石膏厂家,腻子粉批发,永康家德兴,永康市家德兴建材厂 | 苏州教学设备-化工教学设备-环境工程教学模型|同科教仪 | 「银杏树」银杏树行情价格_银杏树种植_山东程锦园林 | 编织人生 - 权威手工编织网站,编织爱好者学习毛衣编织的门户网站,织毛衣就上编织人生网-编织人生 | 飞飞影视_热门电影在线观看_影视大全 | ★济南领跃标识制作公司★济南标识制作,标牌制作,山东标识制作,济南标牌厂 | 振动筛,震动筛,圆形振动筛,振动筛价格,振动筛厂家-新乡巨宝机电 蒸汽热收缩机_蒸汽发生器_塑封机_包膜机_封切收缩机_热收缩包装机_真空机_全自动打包机_捆扎机_封箱机-东莞市中堡智能科技有限公司 | 等离子表面处理机-等离子表面活化机-真空等离子清洗机-深圳市东信高科自动化设备有限公司 | 灌装封尾机_胶水灌装机_软管灌装封尾机_无锡和博自动化机械制造有限公司 | 电位器_轻触开关_USB连接器_广东精密龙电子科技有限公司 | 两头忙,井下装载机,伸缩臂装载机,30装载机/铲车,50装载机/铲车厂家_价格-莱州巨浪机械有限公司 | 临沂招聘网_人才市场_招聘信息_求职招聘找工作请认准【马头商标】 | 东莞动力锂电池保护板_BMS智能软件保护板_锂电池主动均衡保护板-东莞市倡芯电子科技有限公司 | 防腐木批发价格_深圳_惠州_东莞防腐木厂家_森源(深圳)防腐木有限公司 |