The content of this article is about the thread safety of PHP7 kernel analysis 10. Now I share it with you. Friends in need can refer to it
1. Thread safety resource manager
Most of PHP's SAPIs are single-threaded environments, such as cli, fpm, and cgi. Each process only starts one main thread. There is no thread safety issue in this mode, but there are also multi-threaded environments. , such as Apache, in this case you need to consider the issue of thread safety, because there are many global variables in PHP, such as the most common ones: EG, CG. If multiple threads share the same variable, it will conflict, so PHP has many The thread application model provides a safety mechanism: Zend Thread Safe (ZTS).
PHP abstracts a Thread Safe Resource Manager (TSRM) specifically to solve the problem of thread safety. The implementation principle is relatively simple: since it is so difficult to share resources, then just don’t share them. Threads no longer share the same global variable, but each makes a copy. When using data, each thread takes its own copy without interfering with each other.
typedef struct { size_t size; //资源的大小 ts_allocate_ctor ctor; //初始化函数 ts_allocate_dtor dtor; int done; } tsrm_resource_type; struct _tsrm_tls_entry { void **storage; //资源数组 int count; //拥有的资源数:storage数组大小 THREAD_T thread_id; //所属线程id tsrm_tls_entry *next; };
If a resource will be used by multiple threads, you first need to register the resource with TSRM in advance. Then TSRM assigns a unique number to the resource and saves the size, initialization function, etc. of the resource to a In the tsrm_resource_type structure, each thread can only access this resource through the number assigned by TSRM; then when the thread obtains the resource with this number, if TSRM finds that it is the first request, it will allocate a piece of memory based on the resource size at registration, and then Call the initialization function to initialize and save this resource for subsequent use by this thread.
Each thread has a tsrm_tls_entry structure. All resources of the current thread are stored in the storage array, and the subscript is the id of each resource. In addition, the tsrm_tls_entry structure of all threads is saved in an array: tsrm_tls_table, which is a global variable. The position of each thread's tsrm_tls_entry structure in this array is obtained modulo the thread ID and the preset number of threads (tsrm_tls_table_size), that is It is said that multiple threads may be stored in the same location of tsrm_tls_table, so tsrm_tls_entry is a linked list. When looking for resources, first get a tsrm_tls_entry based on: thread id % tsrm_tls_table_size, and then start traversing the linked list to compare thread_id to determine whether it belongs to the current thread.Thread Local Storage (TLS), after creating the tsrm_tls_entry of the current thread, this value will be saved to the TLS of the current thread, so that when ts_resource() obtains resources, it can be directly used through tsrm_tls_get() Got it, saving time on locking and retrieval.
PHP7 kernel Analysis of memory management in 9
PHP7 kernel analysis of 8 and the like
PHP7 kernel analysis of 7 Zend engine execution process
The above is the detailed content of PHP7 Kernel Analysis 10 Thread Safety. For more information, please follow other related articles on the PHP Chinese website!