The content of this article is about PHP7 kernel anatomy 10 thread safety, now share to everyone, the need for friends can refer to
1. Thread Safety Explorer
PHP SAPI Most of the single-threaded environment, such as the CLI, FPM, CGI, each process will only start a main thread, this mode is not a thread security problem, but also has a multi-threading environment, such as Apache, this situation needs to consider the problem of thread safety, Because there are many global variables in PHP, such as the most common: EG, CG, if multiple threads sharing the same variable will conflict, PHP provides a security mechanism for multithreaded application models: Zend thread Safety (Zend thread safe, ZTS).
PHP specifically to solve the problem of thread safety abstraction a thread Safety Explorer (thread safe Resource mananger, TSRM), the implementation of the principle is relatively simple: since the sharing of resources so difficult then simply not shared, Instead of sharing the same global variable, each thread replicates one copy, each of which takes its own copy and does not interfere with the data.
typedef struct { size_t size;//resource ts_allocate_ctor ctor;//initialization function Ts_allocate_dtor dtor; int done;} Tsrm_resource_type;struct _tsrm_tls_entry { void **storage;//resource array int count;//number of resources owned: storage array size thread_t thread_id; Owning thread ID tsrm_tls_entry *next;};
If a resource is used in multithreading, then first you need to register the resource with TSRM, then tsrm a unique number for the resource, and save the size of the resource, initialization function, etc. into a tsrm_resource_type structure. Each thread can access this resource only through the number assigned by TSRM, and then when the thread takes the number to fetch the resource TSRM if it finds the first request, it allocates a chunk of memory based on the resource size at the time of registration, then initializes the initialization function and saves the resource for subsequent use by the thread.
each thread has a tsrm_tls_entry structure, and all the 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 by an array: Tsrm_tls_table, which is a global variable, where the tsrm_tls_entry structure of each thread is positioned in this array based on the thread ID and the number of pre-set threads (Tsrm_tls_ Table_size), that is, it is possible for multiple threads to be saved in the same location as tsrm_tls_table, so Tsrm_tls_entry is a linked list, looking for resources first based on: thread ID% tsrm_tls_table_ Size gets a tsrm_tls_entry and then begins traversing the list of thread_id to determine whether the current thread is present.
Thread Local Storage (thread locally Storage, TLS), after creating the current thread's tsrm_tls_entry, will save this value to the current thread's TLS, so that the Ts_resource () can be obtained through Tsrm_tls_ Get () is taken directly to save time on lock retrieval.