首頁 後端開發 php教程 单台服务器的PHP进程之间实现共享内存的方法_php技巧

单台服务器的PHP进程之间实现共享内存的方法_php技巧

May 17, 2016 am 08:42 AM
共享記憶體

开发人员要想使php进程实现共享内存的读写,首先就要支持IPC函数,即php编译安装时指定:--enable-shmop  与--enable-sysvsem 两个选项

IPC (Inter-process communication) 是一个Unix标准机制,它提供了使得在同一台主机不同进程之间可以互相的方法。基本的IPC处理机制有3种:它们分别是共享内存、信号量和消息队列。本文中我们主要讨论共享内存和信号量的使用。

在不同的处理进程之间使用共享内存是一个实现不同进程之间相互的好方法。如果你在一个进程中向所共享的内存写入一段信息,那么所有其他的进程也可以看到这段被写入的数据。非常方便。在PHP中有了共享内存的帮助,你可以实现不同进程在运行同一段PHP脚本时返回不同的结果。或实现对PHP同时运行数量的实时查询等等。

共享内存允许两个或者多个进程共享一给定的存储区。因为数据不需要在客户机和服务器之间复制,所以这是最快的一种IPC。使用共享内存的唯一窍门是多个进程对一给定存储区的同步存取。

如何建立一个共享内存段呢?下面的代码可以帮你建立共享内存。

复制代码 代码如下:
$shm_id = shmop_open($key, $mode, $perm, $size);

注意,每个共享内存段都有一个唯一的ID, 在PHP中,shmop_open会把建立好的共享内存段的ID返回,这里我们用$shm_id记录它。而$key是一个我们逻辑上表示共享内存段的Key值。不同进程只要选择同一个Key id就可以共享同一段存储段。习惯上我们用一个串(类似文件名一样的东西)的散列值作为key id. $mode指明了共享内存段的使用方式。这里由于是新建,因此值为'c' –取create之意。如果你是已经建立过的共享内存那么请用'a', 取access之意。$perm参数定义了的权限,8进制,关于权限定义请看UNIX文件系统帮助。$size定义了共享内存的大小。尽管有点象fopen(文件处理)你可不要当它同文件处理一样。后面的描述你将看到这一点。

例如:

复制代码 代码如下:
$shm_id = shmop_open(0xff3, "c", 0644, 100);

这里我们打开了一个共享内存段 键值0xff3 –rw-r—r—格式,大小为100字节。

如果需要已有的共享内存段,你必须在调用shmop_open中设第3、4个参数为0。

在Unix下,你可以用一个命令行程序ipcs查询系统所有的IPC资源状态。不过有些系统要求需要超级用户方能执行。下图是一段ipcs的运行结果。

上图中系统显示了4个共享内存段,注意其中第4个键值为0x00000ff3的就是我们刚刚运行过的PHP程序所创建的。关于ipcs的用法请参考UNIX用户手册。

如何释放共享内存呢

释放共享内存的办法是调用PHP指令:shmop_delete($id)

复制代码 代码如下:
shmop_delete($id);

$id 就是你调用shmop_open所存的shmop_op的返回值。还有一个办法就是用UNIX的管理指令:

ipcrm id, id就是你用ipcs看到的ID.和你程序中的$id不一样。不过要小心,如果你用ipcrm直接删除共享内存段那么有可能导致其他不知道这一情况的进程在引用这个已经不复存在的共享内存器时出现一些不可预测的错误(往往结果不妙)。

如何使用(读写)共享内存呢

使用如下所示函数向共享内存写入数据

复制代码 代码如下:
int shmop_write (int shmid, string data, int offset)

其中shmid是用shmop_open返回的句柄。$Data变量存放了要存放的数据。$offset描述了写入从共享内存的开始第一个字节的位置(以0开始)。

读取操作是:

复制代码 代码如下:
string shmop_read (int shmid, int start, int count)

同样,指明$shmid,开始偏移量(以0开始)、总读取数量。返回结果串。这样,你就可以把共享内存段当作是一个字节数组。读几个再写几个,想干嘛就干嘛,十分方便。

现在,在单独的一个PHP进程中读写、创建、删除共享内存方面上你应该没有问题了。但是,显然实际运行中不可能只是一个PHP进程在运行中。如果在多个进程的情况下你还是沿用单个进程的处理方法,你一定会碰到问题--著名的并行和互斥问题。比如说有2个进程同时需要对同一段内存进行读写。当两个进程同时执行写入操作时,你将得到一个错误的数据,因为该段内存将之可能是最后执行的进程的内容,甚至是由2个进程写入的数据轮流随机出现的一段混合的四不象。这显然是不能接受的。为了解决这个问题,我们必须引入互斥机制。互斥机制在很多操作系统的教材上都有专门讲述,这里不多重复。实现互斥机制的最简单办法就是使用信号灯。信号量是另外一种进程间(IPC)的方式,它同其他IPC机构(管道、FIFO、消息队列)不同。它是一个记数器,用于控制多进程对共享数据的存储。同样的是你可以用ipcs和ipcrm实现对信号灯使用状态的查询和对其实现删除操作。在PHP中你可以用下列函数创建一个新的信号量并返回操作该信号量的句柄。如果该key指向的信号量已经存在,sem_get直接返回操作该信号量的句柄。

复制代码 代码如下:
int sem_get(int key [, int max_acquire [, int perm]])

$max_acquire 指明同时最多可以用几个进程进入该信号而不必等待该信号被释放(也就是最大同时处理某一资源的进程数目,一般该值均为一)。$perm指明了权限。

一旦你成功的拥有了一个信号量,你对它所能做的只有2种:请求、释放。当你执行释放操作时, 系统将把该信号值减一。如果小于0那就还设为0。而当你执行请求操作时,系统将把该信号值加一,如果该值大于设定的最大值那么系统将挂起你的处理进程直到其他进程释放到小于最大值为止。一般情况下最大值设为1,这样一来当一个进程获得请求时其他后面的进程只能等待它退出互斥区后释放信号量才能进入该互斥区并同时设为独占方式。这样的信号量常称为双态信号量。当然,如果初值是任意一个正数就表明有多少个共享资源单位可供共享应用。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
win10gpu共享記憶體關閉方法 win10gpu共享記憶體關閉方法 Jan 12, 2024 am 09:45 AM

對電腦有了解的小伙伴肯定都知道gpu有著共享內存,而許多小伙伴都擔心共享內存會導致內存數變小影響電腦而想著關閉它,下面就給大家帶來了關閉它的方法,一起看看吧。 win10gpu共享記憶體關閉:註:GPU的共享記憶體是無法關閉的,但是可以將它的數值設定為最小值。 1.開機時按DEL進入BIOS,部分主機板需要按F2/F9/F12進入,在BIOS介面的最上方有很多Tab,包含「Main、Advanced」等等設定,找到「Chipset」選項。在下面的介面中找到SouthBridge設定選項,點擊Enter進入

Golang函數的多進程之間共享記憶體的應用方法 Golang函數的多進程之間共享記憶體的應用方法 May 17, 2023 pm 12:52 PM

Golang作為一門高並發程式語言,其內建的協程機制和多執行緒操作實現了輕量級的多工處理。然而,在多進程處理的場景下,不同進程之間的通訊和共享記憶體成為了程式開發的關鍵問題。本文將介紹在Golang中實作多進程之間共享記憶體的應用方法。一、Golang中多進程的實作方式在Golang中,可以透過多種方式實現多進程並發處理,其中包括fork、os.Process、

PHP共享記憶體函數用法及應用 PHP共享記憶體函數用法及應用 Jun 16, 2023 pm 12:27 PM

PHP共享記憶體函數用法及應用共享記憶體是指多個進程同時存取同一段記憶體空間的技術。在同時編程中,共享記憶體可用於進程間通信,從而實現不同進程之間的資料共享。 PHP也提供了相關的共享記憶體函數,這篇文章將介紹PHP共享記憶體函數的用法,並且探討一些實際應用場景。共享記憶體函數的使用PHP提供了shmop這個擴充模組,使得PHP可以對系統共享記憶體進行操作。此擴充模組提供的函

多進程編程中遇到的Python問題及解決方法 多進程編程中遇到的Python問題及解決方法 Oct 08, 2023 pm 04:57 PM

多進程程式設計中遇到的Python問題及解決方法,需要具體程式碼範例在Python中,多進程程式設計是一種常用的並發程式設計方式。它可以有效利用多核心處理器的優勢,提高程式的運作效率。然而,在進行多進程編程時,我們也會遇到一些問題。本文將介紹幾個常見的問題,並給出相應的解決方法和程式碼範例。問題1:進程間通訊在多進程程式設計中,進程之間通訊是一個基本的需求。然而,由於進程有各自獨

在C++中使用共享記憶體和訊息佇列 在C++中使用共享記憶體和訊息佇列 Aug 22, 2023 pm 04:21 PM

在C++中,共享記憶體和訊息佇列是兩個常用的進程間通訊方式。它們可以幫助我們在不同的進程之間共享數據和訊息,從而實現更有效率的程式設計。共享記憶體是一種特殊的記憶體區域,可以被多個進程共享。使用共享記憶體可以避免複製資料的開銷,也能夠減少資料在進程間傳輸的延遲。 C++中使用共享記憶體需要包含&lt;sys/shm.h&gt;頭文件,並使用shmget、shmat、sh

如何利用Redis和D語言開發共享記憶體功能 如何利用Redis和D語言開發共享記憶體功能 Sep 22, 2023 am 09:57 AM

如何利用Redis和D語言開發共享記憶體功能概述:隨著電腦應用的複雜性和資料處理的需求增加,共享記憶體成為了一種常用的資料交換方式。 Redis是一款高效能的記憶體資料庫,提供了豐富的資料結構和支援。本文將介紹如何利用Redis和D語言開發共享記憶體功能,並附上具體程式碼範例。步驟1:安裝Redis和D語言編譯器首先,需要在電腦上安裝Redis和D語言編譯器。 Red

如何在 Go 中建立一個共享記憶體的 Goroutine? 如何在 Go 中建立一個共享記憶體的 Goroutine? Jun 02, 2024 am 11:32 AM

可以透過channel實現共享記憶體的Goroutine:建立一個channel以指定元素類型。啟動一個Goroutine向channel寫入資料。在主Goroutine中使用range循環從channel讀取資料。透過關閉channel表示完成寫入。

PHP多執行緒程式設計實作:使用共享記憶體進行多進程通信 PHP多執行緒程式設計實作:使用共享記憶體進行多進程通信 Jun 29, 2023 pm 12:50 PM

PHP是一種廣泛應用於Web開發的腳本語言,一般情況下,它是單執行緒執行的。但是,在某些特定的場景下,我們可能需要使用多執行緒程式設計來提升程式的效能和效率。本文將介紹如何在PHP中進行多執行緒編程,並使用共享記憶體來實現多進程之間的通訊。首先,我們需要了解什麼是多執行緒程式設計和共享記憶體。多線程程式設計是一種並發程式設計的方式,它允許程式在同一時間內執行多個線程,從而提高程式的執行

See all articles