Heim Backend-Entwicklung PHP-Tutorial PHP及Zend Engine的线程安全模型分析_PHP

PHP及Zend Engine的线程安全模型分析_PHP

Jun 01, 2016 pm 12:13 PM
zend

不知道怎么回事总是令人不舒服的,因此我通过阅读源码和查阅有限的资料简要了解一下相关机制,本文是我对研究内容的总结。 本文首先解释了线程安全的概念及PHP中线程安全的背景,然后详细研究了PHP的线程安全机制ZTS(Zend Thread Safety)及具体的实现TSRM,研究内容包括相关数据结构、实现细节及运行机制,最后研究了Zend对于单线程和多线程环境的选择性编译问题。

线程安全
线程安全问题,一言以蔽之就是多线程环境下如何安全存取公共资源。我们知道,每个线程只拥有一个私有栈,共享所属进程的堆。在C中,当一个变量被声明在任何函数之外时,就成为一个全局变量,这时这个变量会被分配到进程的共享存储空间,不同线程都引用同一个地址空间,因此一个线程如果修改了这个变量,就会影响到全部线程。这看似为线程共享数据提供了便利,但是PHP往往是每个线程处理一个请求,因此希望每个线程拥有一个全局变量的副本,而不希望请求间相互干扰。 早期的PHP往往用于单线程环境,每个进程只启动一个线程,因此不存在线程安全问题。后来出现了多线程环境下使用PHP的场景,因此Zend引入了Zend线程安全机制(Zend Thread Safety,简称ZTS)用于保证线程的安全。

ZTS的基本原理及实现
基本思想
说起来ZTS的基本思想是很直观的,不是就是需要每个全局变量在每个线程都拥有一个副本吗?那我就提供这样的机制: 在多线程环境下,申请全局变量不再是简单声明一个变量,而是整个进程在堆上分配一块内存空间用作“线程全局变量池”,在进程启动时初始化这个内存池,每当有线程需要申请全局变量时,通过相应方法调用TSRM(Thread Safe Resource Manager,ZTS的具体实现)并传递必要的参数(如变量大小等等),TSRM负责在内存池中分配相应内存区块并将这块内存的引用标识返回,这样下次这个线程需要读写此变量时,就可以通过将唯一的引用标识传递给TSRM,TSRM将负责真正的读写操作。这样就实现了线程安全的全局变量。下图给出了ZTS原理的示意图:
imageThread1和Thread2同属一个进程,其中各自需要一个全局变量Global Var,TSRM为两者在线程全局内存池中(黄色部分)各自分配了一个区域,并且通过唯一的ID进行标识,这样两个线程就可以通过TSRM存取自己的变量而互不干扰。 下面通过具体的代码片段看一下Zend具体是如何实现这个机制的。这里我用的是PHP5.3.8的源码。 TSRM的实现代码在PHP源码的“TSRM”目录下。

数据结构
TSRM中比较重要的数据结构有两个:tsrm_tls_entry和tsrm_resource_type。下面先看tsrm_tls_entry。 tsrm_tls_entry定义在TSRM/TSRM.c中:
复制代码 代码如下:
typedef struct _tsrm_tls_entry tsrm_tls_entry;

struct _tsrm_tls_entry {
void **storage;
int count;
THREAD_T thread_id;
tsrm_tls_entry *next;
}

每个tsrm_tls_entry结构负责表示一个线程的所有全局变量资源,其中thread_id存储线程ID,count记录全局变量数,next指向下一个节点。storage可以看做指针数组,其中每个元素是一个指向本节点代表线程的一个全局变量。最终各个线程的tsrm_tls_entry被组成一个链表结构,并将链表头指针赋值给一个全局静态变量tsrm_tls_table。注意,因为tsrm_tls_table是一个货真价实的全局变量,所以所有线程会共享这个变量,这就实现了线程间的内存管理一致性。tsrm_tls_entry和tsrm_tls_table结构的示意图如下:
imagetsrm_resource_type的内部结构相对简单一些:
复制代码 代码如下:
typedef struct {
size_t size;
ts_allocate_ctor ctor;
ts_allocate_dtor dtor;
int done;
}

tsrm_resource_type;上文说过tsrm_tls_entry是以线程为单位的(每个线程一个节点),而tsrm_resource_type以资源(或者说全局变量)为单位,每次一个新的资源被分配时,就会创建一个tsrm_resource_type。所有tsrm_resource_type以数组(线性表)的方式组成tsrm_resource_table,其下标就是这个资源的ID。每个tsrm_resource_type存储了此资源的大小和构造、析构方法指针。某种程度上,tsrm_resource_table可以看做是一个哈希表,key是资源ID,value是tsrm_resource_type结构。

实现细节
这一小节分析TSRM一些算法的实现细节。因为整个TSRM涉及代码比较多,这里拣其中具有代表性的两个函数分析。 第一个值得注意的是tsrm_startup函数,这个函数在进程起始阶段被sapi调用,用于初始化TSRM的环境。由于tsrm_startup略长,这里摘录出我认为应该注意的地方:
复制代码 代码如下:
/* Startup TSRM (call once for the entire process) */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename)
{
/* code... */

tsrm_tls_table_size = expected_threads;

tsrm_tls_table = (tsrm_tls_entry **) calloc(tsrm_tls_table_size, sizeof(tsrm_tls_entry *));
if (!tsrm_tls_table) {
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate TLS table"));
return 0;
}
id_count=0;

resource_types_table_size = expected_resources;
resource_types_table = (tsrm_resource_type *) calloc(resource_types_table_size, sizeof(tsrm_resource_type));
if (!resource_types_table) {
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate resource types table"));
free(tsrm_tls_table);
tsrm_tls_table = NULL;
return 0;
}

/* code... */

return 1;
}

其实tsrm_startup的主要任务就是初始化上文提到的两个数据结构。第一个比较有意思的是它的前两个参数:expected_threads和expected_resources。这两个参数由sapi传入,表示预计的线程数和资源数,可以看到tsrm_startup会按照这两个参数预先分配空间(通过calloc)。因此TSRM会首先分配可容纳expected_threads个线程和expected_resources个资源的。要看各个sapi默认会传入什么,可以看各个sapi的源码(在sapi目录下),我简单看了一下:
image可以看到比较常用的sapi如mod_php5、php-fpm和cgi都是预分配一个线程和一个资源,这样是因为不愿浪费内存空间,而且多数情况下PHP还是运行于单线程环境。 这里还可以看到一个id_count变量,这个变量是一个全局静态变量,其作用就是通过自增产生资源ID,这个变量在这里被初始化为0。所以TSRM产生资源ID的方式非常简单:就是一个整形变量的自增。 第二个需要仔细分析的就是ts_allocate_id,编写过PHP扩展的朋友对这个函数肯定不陌生,这个函数...

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So verwenden Sie ACL (Access Control List) zur Berechtigungskontrolle im Zend Framework So verwenden Sie ACL (Access Control List) zur Berechtigungskontrolle im Zend Framework Jul 29, 2023 am 09:24 AM

So verwenden Sie ACL (AccessControlList) zur Berechtigungskontrolle im Zend Framework. Einführung: In einer Webanwendung ist die Berechtigungskontrolle eine entscheidende Funktion. Es stellt sicher, dass Benutzer nur auf die Seiten und Funktionen zugreifen können, für die sie eine Zugriffsberechtigung haben, und verhindert unbefugten Zugriff. Das Zend-Framework bietet eine praktische Möglichkeit, die Berechtigungskontrolle mithilfe der ACL-Komponente (AccessControlList) zu implementieren. In diesem Artikel wird die Verwendung von ACL im Zend Framework vorgestellt

PHP-Implementierungs-Framework: Zend Framework-Erste-Schritte-Tutorial PHP-Implementierungs-Framework: Zend Framework-Erste-Schritte-Tutorial Jun 19, 2023 am 08:09 AM

PHP-Implementierungsframework: ZendFramework-Einführungs-Tutorial ZendFramework ist ein von PHP entwickeltes und derzeit von ZendTechnologies verwaltetes Open-Source-Website-Framework, das das MVC-Designmuster übernimmt und eine Reihe wiederverwendbarer Codebibliotheken zur Implementierung von Web2.0-Anwendungen und Web Serve bereitstellt. ZendFramework ist bei PHP-Entwicklern sehr beliebt und geschätzt und bietet eine große Auswahl an

PHP erkennt ZendOptimizer nicht, wie kann man das lösen? PHP erkennt ZendOptimizer nicht, wie kann man das lösen? Mar 19, 2024 pm 01:09 PM

PHP erkennt ZendOptimizer nicht, wie kann man das lösen? Bei der PHP-Entwicklung kann es manchmal vorkommen, dass PHP ZendOptimizer nicht erkennt, was dazu führt, dass einige PHP-Codes nicht ordnungsgemäß ausgeführt werden. In diesem Fall müssen wir einige Maßnahmen ergreifen, um das Problem zu lösen. Im Folgenden werden einige mögliche Problemumgehungen zusammen mit spezifischen Codebeispielen beschrieben. 1. Bestätigen Sie, ob ZendOptimizer korrekt installiert ist: Zuerst müssen wir bestätigen, dass ZendOptimizer

So konfigurieren Sie die Windows2003 IIS+MySQL+PHP+Zend-Umgebung So konfigurieren Sie die Windows2003 IIS+MySQL+PHP+Zend-Umgebung Jun 02, 2023 pm 09:56 PM

Das Installationspaket für Windows 2003 umfasst Zend, PHP5.2.17, PHPWind8.7 und PHPMyadmin3.5.2. Sie können das Installationspaket direkt herunterladen, um Zeit bei der Suche nach Ressourcen zu sparen. Da MySQL jedoch das Upload-Limit überschritten hat, müssen Sie zum Herunterladen auf die offizielle MySQL-Website gehen. Dann entpacken und auf das Laufwerk D kopieren, wie unten gezeigt: MySQLinDdisk Installieren und konfigurieren Sie WindowsIIS+FTP. Klicken Sie auf Start > Systemsteuerung > Programme hinzufügen oder entfernen.Hinzufügen oder Löschen eines PG Klicken Sie auf „Windows-Komponenten hinzufügen/entfernen“ (A). Addingorde

Wie Sie mit dem PHP-Framework Zend eine effiziente ERP-Management-Plattform entwickeln Wie Sie mit dem PHP-Framework Zend eine effiziente ERP-Management-Plattform entwickeln Jun 26, 2023 pm 11:00 PM

Mit der rasanten Entwicklung der Informationstechnologie erkennen immer mehr Unternehmen die Notwendigkeit des Informationsmanagements. Die ERP-Managementplattform (Enterprise Resource Planning) ist ein wichtiges Werkzeug für die moderne Unternehmensführung, das Unternehmen dabei helfen kann, Ressourcenplanung, Zusammenarbeit, Kontrolle, Optimierung und Verwaltung zu realisieren. Unter ihnen ist das PHP-Framework Zend ein hervorragendes Entwicklungstool, das Entwicklern helfen kann, ERP-Systeme schnell und effizient zu entwickeln. In diesem Artikel wird erläutert, wie Sie mit Zend eine effiziente ERP-Verwaltungsplattform entwickeln. 1. Bestimmen Sie die Anforderungsanalyse, bevor Sie mit dem Entwicklungsprozess beginnen

Laravel vs. Zend: Welches Framework eignet sich besser für die Entwicklung großer Anwendungen? Laravel vs. Zend: Welches Framework eignet sich besser für die Entwicklung großer Anwendungen? Jun 19, 2023 am 08:52 AM

Mit der kontinuierlichen Weiterentwicklung von Internetanwendungen steigt auch die Nachfrage nach der Entwicklung groß angelegter Anwendungen. In diesem Zusammenhang ist es besonders wichtig, ein Entwicklungsframework zu wählen, das zu Ihnen passt. Laravel und Zend sind zwei weit verbreitete PHP-Frameworks. Sie haben jeweils ihre eigenen Vorteile, aber welches eignet sich besser für die Entwicklung umfangreicher Anwendungen? Laravel ist ein beliebtes Entwicklungsframework, das zu einem der bevorzugten Frameworks für PHP-Entwickler geworden ist. Es verfügt über ein modernes Designkonzept und verfügt über eine Vielzahl leistungsstarker integrierter Funktionen und Tools, wie z. B. EloquentOR

Symfony 3 vs. Zend Framework 3: Mit welchem ​​PHP-Framework ist der Einstieg einfacher? Symfony 3 vs. Zend Framework 3: Mit welchem ​​PHP-Framework ist der Einstieg einfacher? Jun 19, 2023 am 09:46 AM

PHP ist eine weit verbreitete dynamische Web-Programmiersprache. Entwickler können verschiedene Frameworks nutzen, um ihre Webentwicklungsarbeit zu vereinfachen. Symfony und ZendFramework sind eines der beiden beliebtesten Frameworks in PHP. Anfänger sind bei der Wahl zwischen Symfony3 und ZendFramework3 oft verwirrt. Hier vergleichen wir diese beiden Frameworks, um herauszufinden, mit welchem ​​Framework der Einstieg einfacher ist. Symfony3Symfony ist ein PH, der auf dem MVC-Modell basiert

Entwickeln Sie eine leistungsstarke Suchmaschine mit dem PHP-Framework Zend Entwickeln Sie eine leistungsstarke Suchmaschine mit dem PHP-Framework Zend Jun 27, 2023 am 08:36 AM

Mit dem explosionsartigen Wachstum der Internetinformationen sind Suchmaschinen zu einer der bevorzugten Möglichkeiten für Menschen geworden, Informationen zu erhalten. Da die Anzahl der Websites immer weiter zunimmt, werden die schnelle Reaktion und Genauigkeit von Suchmaschinen immer wichtiger, was eine hohe Leistung der Suchmaschinen erfordert. In diesem Artikel werde ich vorstellen, wie man mit dem PHP-Framework Zend eine leistungsstarke Suchmaschine entwickelt. 1. Warum Zend Framework verwenden? Zend Framework ist ein leistungsstarkes PHP-Framework mit hervorragender Leistung und Skalierbarkeit.

See all articles