SlideShare uma empresa Scribd logo
1 de 43
and threads
Zend Thread Safety
Hello everybody
 Julien PAULI
 Programming in PHP since early 2000s
 PHP Internals hacker and trainer
 PHP 5.5/5.6 Release Manager
 Working at SensioLabs in Paris - Blackfire
 Writing PHP tech articles and books
 http://phpinternalsbook.com
 @julienpauli - github.com/jpauli - jpauli@php.net
 Like working on OSS such as PHP :-)
TOC
 Recall on computer parallel programming
 What are threads ?
 Threads VS process
 The PHP multi-tasking model
 Zend Thread Safe mode
 What - why - how ?
 Parallel programming with PHP
 pcntl
 pthread
Computer architecture
 Nowadays we own machines
 With several CPUs
 With several-core CPUs
 Multitasking
 Time division of one CPU frequency
 Concurrency
 Using several CPUs (or Core) at the same time
 Parallelism
 Both above solutions mixed
Concurrency
Parallelism
OS Process
 The lowest level representation of "a task"
 The OS scheduler does the job
Processes are heavy
 Processes are heavy guys
 Creating a process means a lot of work for the Kernel
 Lots of CPU instructions involved
 Many memory movements
 A process eats some memory
 For its own structures
Threads
Thread infos
Threads are light process
 Threads have been designed like processes
 But their goal
 is to be lighter
 is to be userland programmable
 They thus share some data between them
 They are lighter to create
 Less structure involved
 Less memory access / movement on management
Thread model
Threads share memory
 Threads leave in processes
 If the process dies, all its threads die
 Threads share their process'
 heap
 data
 sigmask
 FDs
 Threads got their own
 stack
 sigmask
 CPU registers
Threads dangers
 Threads share the heap and the data segment
 Thus while programming, threads share the
global state
 Accessing the global state with several threads
 Needs extra care
 Memory barriers
 Semaphores and locks
Threads VS processes
 Threads
 Will by default share memory
 Will share file descriptors
 Will share filesystem context
 Will share signal handling
 Processes
 Will by default not share memory
 Most file descriptors not shared
 Don't share filesystem context
 Don't share signal handling
PHP Multitasking
 Since 1995 ...
 Rely on the webserver to process several requests at
the same time
 Rely on FastCGI
users
Multitasking PHP
 To treat several requests
 The webserver embedding PHP forks itself
 Apache
 The webserver forks itself and pass the web request
to PHP CGI processes
 Using FastCGI : PHP forks itself
 php-fpm
PHP in a threaded env
 PHP could leave in a threaded environment
 If the webserver uses threads to handle concurrency
 Apache with mpm_worker
 IIS under Windows
 Windows heavily makes use of threads
 Unix tend to prefer using processes
ZTS
Zend Thread Safety
 PHP will never itself make use threads
 PHP's code is NOT threaded
 But PHP could, despite him, live in threads
 PHP thus needs to be programmed
 So that it can access thread shared memory safely
 This is called the Zend Thread Safe mode : ZTS
ZTS goals
 ZTS is a way of programming PHP core and
extensions , in C
 A layer that eases access to globals and turn
them thread-safe using one OS supported
thread lib
 Let's see how
ZTS, abstract thread model
 Several thread library exists
 They all got their own behavior / API / performances
 ZTS provides macros and automation to abstract
that
 ZTS supports
 GNU Pth
 POSIX Thread (pthread)
 SGI's State Thread
 BeOS Threads
 Choose at compile time (--with-tsrm-???)
TSRM
 TSRM stands for Thread Safe Resource Manager
 This is the C code layer behind ZTS mode
 TSRM/ in PHP source code
 Activate using --enable-maintainer-zts
 This will build a ZTS PHP
Example program
static int val; /* true global */
PHP_MINIT(wow_ext) /* PHP Module initialization */
{
if (something()) {
val = 3; /* writing to a true global */
}
}
PHP_RINIT(wow_ext) /* PHP Request initialization */
{
if (something()) {
WOW_G(val) = 3; /* writing to a thread global */
}
}
TSRM macros
 Accessing globals while in a thread must be
done using TSRM macros
#ifndef ZTS
#define WOW_G(v) wow_globals.v
#else
#define WOW_G(v) (((wow_globals *)
(*((void ***) tsrm_get_ls_cache()))[((wow_globals_id)-1)])->v)
#endif
How all this stuff work ?
Pthread keys
 In pthread, each thread is given a key.
 That key is used to access a TLS : Thread Local
Storage
 A piece of memory owned by each thread
 The compiler takes care of the hard job
 This is where we'll store our "globals"
Extensions compilation
 At compilation, each extension declares
 a pointer to some TLS space
 __thread is used
 An id (integer) which will retain this extension
specific storage
BF_DECLARE_ZEND_GLOBALS
ts_rsrc_id blackfire_globals_id; __thread void *_tsrm_ls_cache = ((void *)0);;
TLS storage detail
TLS #1 TLS #2 TLS #3 ...
void *storage
TLS storage detail
TLS #1
ext storage id ext/core
ext/xml
ext/pcre
ext/gz
ext/blackfire
TLS #2
ext/core
ext/xml
ext/pcre
ext/gz
ext/blackfire
TLS #3
ext/core
ext/xml
ext/pcre
ext/gz
ext/blackfire
void *storage
Allocating resources per thread
 This is done at every new request
 ts_resource_ex() checks if this thread's got data
 If not, it calls for allocate_new_resource()
 This will set the thread storage using the current thread key
Allocating thread resources
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr,
THREAD_T thread_id)
{
int i;
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
(*thread_resources_ptr)->count = id_count;
(*thread_resources_ptr)->thread_id = thread_id;
(*thread_resources_ptr)->next = NULL;
/* Set thread local storage to this new thread resources structure */
tsrm_tls_set(*thread_resources_ptr);
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
if (resource_types_table[i].ctor) {
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i]);
}
tsrm_mutex_unlock(tsmm_mutex);
}
Extensions thread startup
 For each new thread, extensions should read
the local storage ...
PHP_GINIT_FUNCTION(blackfire)
{
#ifdef ZTS
ZEND_TSRMLS_CACHE_UPDATE();
#endif
/* ... ... */
}
_tsrm_ls_cache = tsrm_get_ls_cache();
_tsrm_ls_cache = pthread_getspecific(tls_key);
Accessing resources per thread
 For each new thread, extensions should read
the local storage ...
 To better read their own memory part after
#define BF_G(v)
(((zend_blackfire_globals *) (*((void ***) _tsrm_ls_cache))[((blackfire_globals_id)-1)])->(v))
Thread Safe Resource Mana
_ Local Storage _ cache
extension storage id
ZTS ?
 A nice layer, that eases and abstract all the
thread and TLS management
 If you use the cache, then it is fully performant
 Compile PHP with
-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1
 However, it slows down PHP's startup
 We don't care
 It slows down request creation for every new
thread
 That is however clearly acceptable
When to use ZTS ?
 If you run Windows with Apache
 Threads are used , so compile with ZTS
 If you run Unix and need ZTS
 You use an extension that needs the interpreter to be
built with ZTS
 Like the pthread extension
 You use some kind of webserver that embed PHP and
makes use of threads
 Like Apache with mpm_worker
 In a HUGE majorty of cases, you'll use Unix, and
you won't need ZTS
Check if ZTS is used
 Use the PHP_ZTS constant in PHP
 See the output of php -v
 See the output of phpinfo()
 As a PHP developer, you shouldn't care about ZTS
in your code
 As a PHP extension developer, you should be
aware of how it works, and use dedicated macros
ZTS ABI
 Obviously, ZTS ABI is not compatible with NTS
ABI
 Thus extensions must be rebuilt
 Check their install dir
Using threads in PHP Land
 This is possible
 You need ext/pthread for that
 http://php.net/manual/fr/book.pthreads.php
 http://pthreads.org/
 This is experimental
 You must really be used to thread programming
to use ext/pthread
Using threads in PHP Land
 Not really a good idea
 At least, there exists better languages for that
 C , C++ or Java
 Those are languages designed to provide thread
usage
 PHP is not !
 You should not need to parallelize tasks when
using the PHP language
 If so, then probably you should use another language
Using processes in PHP land
 ext/pcntl
 I guess you already know it
 It shadows Unix processes
 Know your machine and your OS
 Obviously not available for Windows
 fork(), wait(), waitpid(), signal() ...
 All those calls are syscalls available using C
 Consider using C for true performances and to finely
master what you do
 Even if PHP adds a really thin layer on top of that stuf
ZTS and threads : concluding
 PHP is thread-safe
 Compile with --enable-maintainer-zts
 You'll activate Zend Thread Safety
 You only need ZTS is some uncommon specific
cases
 Take care of "exotic" extensions
 They may not be thread-safe themselves
 Analyze before using them
 Please don't blindly blame PHP
Thank you for listening

Mais conteúdo relacionado

Mais procurados

netfilter and iptables
netfilter and iptablesnetfilter and iptables
netfilter and iptables
Kernel TLV
 
High-Performance Networking Using eBPF, XDP, and io_uring
High-Performance Networking Using eBPF, XDP, and io_uringHigh-Performance Networking Using eBPF, XDP, and io_uring
High-Performance Networking Using eBPF, XDP, and io_uring
ScyllaDB
 
BPF: Tracing and more
BPF: Tracing and moreBPF: Tracing and more
BPF: Tracing and more
Brendan Gregg
 

Mais procurados (20)

淺談探索 Linux 系統設計之道
淺談探索 Linux 系統設計之道 淺談探索 Linux 系統設計之道
淺談探索 Linux 系統設計之道
 
쿠버네티스 기반 PaaS 솔루션 - Playce Kube를 소개합니다.
쿠버네티스 기반 PaaS 솔루션 - Playce Kube를 소개합니다.쿠버네티스 기반 PaaS 솔루션 - Playce Kube를 소개합니다.
쿠버네티스 기반 PaaS 솔루션 - Playce Kube를 소개합니다.
 
擁抱開源:企業應如何善用開源技術,才能得其利而防其弊-加強版
擁抱開源:企業應如何善用開源技術,才能得其利而防其弊-加強版擁抱開源:企業應如何善用開源技術,才能得其利而防其弊-加強版
擁抱開源:企業應如何善用開源技術,才能得其利而防其弊-加強版
 
Introduction to eBPF
Introduction to eBPFIntroduction to eBPF
Introduction to eBPF
 
TC Flower Offload
TC Flower OffloadTC Flower Offload
TC Flower Offload
 
Tiered Compilation in Hotspot JVM
Tiered Compilation in Hotspot JVMTiered Compilation in Hotspot JVM
Tiered Compilation in Hotspot JVM
 
eBPF maps 101
eBPF maps 101eBPF maps 101
eBPF maps 101
 
EBPF and Linux Networking
EBPF and Linux NetworkingEBPF and Linux Networking
EBPF and Linux Networking
 
DoS and DDoS mitigations with eBPF, XDP and DPDK
DoS and DDoS mitigations with eBPF, XDP and DPDKDoS and DDoS mitigations with eBPF, XDP and DPDK
DoS and DDoS mitigations with eBPF, XDP and DPDK
 
BPF Internals (eBPF)
BPF Internals (eBPF)BPF Internals (eBPF)
BPF Internals (eBPF)
 
Docker Networking - Common Issues and Troubleshooting Techniques
Docker Networking - Common Issues and Troubleshooting TechniquesDocker Networking - Common Issues and Troubleshooting Techniques
Docker Networking - Common Issues and Troubleshooting Techniques
 
BPF / XDP 8월 세미나 KossLab
BPF / XDP 8월 세미나 KossLabBPF / XDP 8월 세미나 KossLab
BPF / XDP 8월 세미나 KossLab
 
HAProxy 1.9
HAProxy 1.9HAProxy 1.9
HAProxy 1.9
 
Linux kernel tracing
Linux kernel tracingLinux kernel tracing
Linux kernel tracing
 
netfilter and iptables
netfilter and iptablesnetfilter and iptables
netfilter and iptables
 
[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南
 
Introduction to kotlin coroutines
Introduction to kotlin coroutinesIntroduction to kotlin coroutines
Introduction to kotlin coroutines
 
High-Performance Networking Using eBPF, XDP, and io_uring
High-Performance Networking Using eBPF, XDP, and io_uringHigh-Performance Networking Using eBPF, XDP, and io_uring
High-Performance Networking Using eBPF, XDP, and io_uring
 
BPF: Tracing and more
BPF: Tracing and moreBPF: Tracing and more
BPF: Tracing and more
 
USENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame GraphsUSENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame Graphs
 

Semelhante a Php and threads ZTS

Php extensions workshop
Php extensions workshopPhp extensions workshop
Php extensions workshop
julien pauli
 
Integrating Node.js with PHP
Integrating Node.js with PHPIntegrating Node.js with PHP
Integrating Node.js with PHP
Lee Boynton
 
Medical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUsMedical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUs
Daniel Blezek
 
WEEK07operatingsystemdepartmentofsoftwareengineering.pptx
WEEK07operatingsystemdepartmentofsoftwareengineering.pptxWEEK07operatingsystemdepartmentofsoftwareengineering.pptx
WEEK07operatingsystemdepartmentofsoftwareengineering.pptx
babayaga920391
 

Semelhante a Php and threads ZTS (20)

Php extensions workshop
Php extensions workshopPhp extensions workshop
Php extensions workshop
 
Php’s guts
Php’s gutsPhp’s guts
Php’s guts
 
PHP 7 OPCache extension review
PHP 7 OPCache extension reviewPHP 7 OPCache extension review
PHP 7 OPCache extension review
 
Basic Linux Internals
Basic Linux InternalsBasic Linux Internals
Basic Linux Internals
 
Here comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfHere comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdf
 
OpenHPI - Parallel Programming Concepts - Week 3
OpenHPI - Parallel Programming Concepts - Week 3OpenHPI - Parallel Programming Concepts - Week 3
OpenHPI - Parallel Programming Concepts - Week 3
 
Interoperable PHP
Interoperable PHPInteroperable PHP
Interoperable PHP
 
Basics of C
Basics of CBasics of C
Basics of C
 
posix.pdf
posix.pdfposix.pdf
posix.pdf
 
Integrating Node.js with PHP
Integrating Node.js with PHPIntegrating Node.js with PHP
Integrating Node.js with PHP
 
Medical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUsMedical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUs
 
Introduction to node.js GDD
Introduction to node.js GDDIntroduction to node.js GDD
Introduction to node.js GDD
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with Puppet
 
What are thread libraries in operating system
What are thread libraries in operating systemWhat are thread libraries in operating system
What are thread libraries in operating system
 
1032 cs208 g operation system ip camera case share.v0.2
1032 cs208 g operation system ip camera case share.v0.21032 cs208 g operation system ip camera case share.v0.2
1032 cs208 g operation system ip camera case share.v0.2
 
PHP Sessions and Non-Sessions
PHP Sessions and Non-SessionsPHP Sessions and Non-Sessions
PHP Sessions and Non-Sessions
 
Php extensions
Php extensionsPhp extensions
Php extensions
 
WEEK07operatingsystemdepartmentofsoftwareengineering.pptx
WEEK07operatingsystemdepartmentofsoftwareengineering.pptxWEEK07operatingsystemdepartmentofsoftwareengineering.pptx
WEEK07operatingsystemdepartmentofsoftwareengineering.pptx
 
Operating System Chapter 4 Multithreaded programming
Operating System Chapter 4 Multithreaded programmingOperating System Chapter 4 Multithreaded programming
Operating System Chapter 4 Multithreaded programming
 
concurrency
concurrencyconcurrency
concurrency
 

Mais de julien pauli

Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objects
julien pauli
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
julien pauli
 
Understanding PHP memory
Understanding PHP memoryUnderstanding PHP memory
Understanding PHP memory
julien pauli
 
Communications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPCommunications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHP
julien pauli
 

Mais de julien pauli (20)

Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019
 
Php engine
Php enginePhp engine
Php engine
 
Dns
DnsDns
Dns
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machine
 
Basics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNGBasics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNG
 
Mastering your home network - Do It Yourself
Mastering your home network - Do It YourselfMastering your home network - Do It Yourself
Mastering your home network - Do It Yourself
 
SymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performancesSymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performances
 
Tcpip
TcpipTcpip
Tcpip
 
Symfony live 2017_php7_performances
Symfony live 2017_php7_performancesSymfony live 2017_php7_performances
Symfony live 2017_php7_performances
 
PHP 7 new engine
PHP 7 new enginePHP 7 new engine
PHP 7 new engine
 
Profiling php5 to php7
Profiling php5 to php7Profiling php5 to php7
Profiling php5 to php7
 
PHP 7 performances from PHP 5
PHP 7 performances from PHP 5PHP 7 performances from PHP 5
PHP 7 performances from PHP 5
 
PHP7 is coming
PHP7 is comingPHP7 is coming
PHP7 is coming
 
Mysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extensionMysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extension
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objects
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)
 
Understanding PHP memory
Understanding PHP memoryUnderstanding PHP memory
Understanding PHP memory
 
Communications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPCommunications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHP
 

Último

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Último (20)

Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 

Php and threads ZTS

  • 2. Hello everybody  Julien PAULI  Programming in PHP since early 2000s  PHP Internals hacker and trainer  PHP 5.5/5.6 Release Manager  Working at SensioLabs in Paris - Blackfire  Writing PHP tech articles and books  http://phpinternalsbook.com  @julienpauli - github.com/jpauli - jpauli@php.net  Like working on OSS such as PHP :-)
  • 3. TOC  Recall on computer parallel programming  What are threads ?  Threads VS process  The PHP multi-tasking model  Zend Thread Safe mode  What - why - how ?  Parallel programming with PHP  pcntl  pthread
  • 4. Computer architecture  Nowadays we own machines  With several CPUs  With several-core CPUs  Multitasking  Time division of one CPU frequency  Concurrency  Using several CPUs (or Core) at the same time  Parallelism  Both above solutions mixed
  • 7. OS Process  The lowest level representation of "a task"  The OS scheduler does the job
  • 8. Processes are heavy  Processes are heavy guys  Creating a process means a lot of work for the Kernel  Lots of CPU instructions involved  Many memory movements  A process eats some memory  For its own structures
  • 11. Threads are light process  Threads have been designed like processes  But their goal  is to be lighter  is to be userland programmable  They thus share some data between them  They are lighter to create  Less structure involved  Less memory access / movement on management
  • 13. Threads share memory  Threads leave in processes  If the process dies, all its threads die  Threads share their process'  heap  data  sigmask  FDs  Threads got their own  stack  sigmask  CPU registers
  • 14. Threads dangers  Threads share the heap and the data segment  Thus while programming, threads share the global state  Accessing the global state with several threads  Needs extra care  Memory barriers  Semaphores and locks
  • 15. Threads VS processes  Threads  Will by default share memory  Will share file descriptors  Will share filesystem context  Will share signal handling  Processes  Will by default not share memory  Most file descriptors not shared  Don't share filesystem context  Don't share signal handling
  • 16. PHP Multitasking  Since 1995 ...  Rely on the webserver to process several requests at the same time  Rely on FastCGI users
  • 17. Multitasking PHP  To treat several requests  The webserver embedding PHP forks itself  Apache  The webserver forks itself and pass the web request to PHP CGI processes  Using FastCGI : PHP forks itself  php-fpm
  • 18. PHP in a threaded env  PHP could leave in a threaded environment  If the webserver uses threads to handle concurrency  Apache with mpm_worker  IIS under Windows  Windows heavily makes use of threads  Unix tend to prefer using processes
  • 19. ZTS
  • 20. Zend Thread Safety  PHP will never itself make use threads  PHP's code is NOT threaded  But PHP could, despite him, live in threads  PHP thus needs to be programmed  So that it can access thread shared memory safely  This is called the Zend Thread Safe mode : ZTS
  • 21. ZTS goals  ZTS is a way of programming PHP core and extensions , in C  A layer that eases access to globals and turn them thread-safe using one OS supported thread lib  Let's see how
  • 22. ZTS, abstract thread model  Several thread library exists  They all got their own behavior / API / performances  ZTS provides macros and automation to abstract that  ZTS supports  GNU Pth  POSIX Thread (pthread)  SGI's State Thread  BeOS Threads  Choose at compile time (--with-tsrm-???)
  • 23. TSRM  TSRM stands for Thread Safe Resource Manager  This is the C code layer behind ZTS mode  TSRM/ in PHP source code  Activate using --enable-maintainer-zts  This will build a ZTS PHP
  • 24. Example program static int val; /* true global */ PHP_MINIT(wow_ext) /* PHP Module initialization */ { if (something()) { val = 3; /* writing to a true global */ } } PHP_RINIT(wow_ext) /* PHP Request initialization */ { if (something()) { WOW_G(val) = 3; /* writing to a thread global */ } }
  • 25. TSRM macros  Accessing globals while in a thread must be done using TSRM macros #ifndef ZTS #define WOW_G(v) wow_globals.v #else #define WOW_G(v) (((wow_globals *) (*((void ***) tsrm_get_ls_cache()))[((wow_globals_id)-1)])->v) #endif
  • 26. How all this stuff work ?
  • 27. Pthread keys  In pthread, each thread is given a key.  That key is used to access a TLS : Thread Local Storage  A piece of memory owned by each thread  The compiler takes care of the hard job  This is where we'll store our "globals"
  • 28. Extensions compilation  At compilation, each extension declares  a pointer to some TLS space  __thread is used  An id (integer) which will retain this extension specific storage BF_DECLARE_ZEND_GLOBALS ts_rsrc_id blackfire_globals_id; __thread void *_tsrm_ls_cache = ((void *)0);;
  • 29. TLS storage detail TLS #1 TLS #2 TLS #3 ... void *storage
  • 30. TLS storage detail TLS #1 ext storage id ext/core ext/xml ext/pcre ext/gz ext/blackfire TLS #2 ext/core ext/xml ext/pcre ext/gz ext/blackfire TLS #3 ext/core ext/xml ext/pcre ext/gz ext/blackfire void *storage
  • 31. Allocating resources per thread  This is done at every new request  ts_resource_ex() checks if this thread's got data  If not, it calls for allocate_new_resource()  This will set the thread storage using the current thread key
  • 32. Allocating thread resources static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id) { int i; (*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry)); (*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count); (*thread_resources_ptr)->count = id_count; (*thread_resources_ptr)->thread_id = thread_id; (*thread_resources_ptr)->next = NULL; /* Set thread local storage to this new thread resources structure */ tsrm_tls_set(*thread_resources_ptr); (*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size); if (resource_types_table[i].ctor) { resource_types_table[i].ctor((*thread_resources_ptr)->storage[i]); } tsrm_mutex_unlock(tsmm_mutex); }
  • 33. Extensions thread startup  For each new thread, extensions should read the local storage ... PHP_GINIT_FUNCTION(blackfire) { #ifdef ZTS ZEND_TSRMLS_CACHE_UPDATE(); #endif /* ... ... */ } _tsrm_ls_cache = tsrm_get_ls_cache(); _tsrm_ls_cache = pthread_getspecific(tls_key);
  • 34. Accessing resources per thread  For each new thread, extensions should read the local storage ...  To better read their own memory part after #define BF_G(v) (((zend_blackfire_globals *) (*((void ***) _tsrm_ls_cache))[((blackfire_globals_id)-1)])->(v)) Thread Safe Resource Mana _ Local Storage _ cache extension storage id
  • 35. ZTS ?  A nice layer, that eases and abstract all the thread and TLS management  If you use the cache, then it is fully performant  Compile PHP with -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1  However, it slows down PHP's startup  We don't care  It slows down request creation for every new thread  That is however clearly acceptable
  • 36. When to use ZTS ?  If you run Windows with Apache  Threads are used , so compile with ZTS  If you run Unix and need ZTS  You use an extension that needs the interpreter to be built with ZTS  Like the pthread extension  You use some kind of webserver that embed PHP and makes use of threads  Like Apache with mpm_worker  In a HUGE majorty of cases, you'll use Unix, and you won't need ZTS
  • 37. Check if ZTS is used  Use the PHP_ZTS constant in PHP  See the output of php -v  See the output of phpinfo()  As a PHP developer, you shouldn't care about ZTS in your code  As a PHP extension developer, you should be aware of how it works, and use dedicated macros
  • 38. ZTS ABI  Obviously, ZTS ABI is not compatible with NTS ABI  Thus extensions must be rebuilt  Check their install dir
  • 39. Using threads in PHP Land  This is possible  You need ext/pthread for that  http://php.net/manual/fr/book.pthreads.php  http://pthreads.org/  This is experimental  You must really be used to thread programming to use ext/pthread
  • 40. Using threads in PHP Land  Not really a good idea  At least, there exists better languages for that  C , C++ or Java  Those are languages designed to provide thread usage  PHP is not !  You should not need to parallelize tasks when using the PHP language  If so, then probably you should use another language
  • 41. Using processes in PHP land  ext/pcntl  I guess you already know it  It shadows Unix processes  Know your machine and your OS  Obviously not available for Windows  fork(), wait(), waitpid(), signal() ...  All those calls are syscalls available using C  Consider using C for true performances and to finely master what you do  Even if PHP adds a really thin layer on top of that stuf
  • 42. ZTS and threads : concluding  PHP is thread-safe  Compile with --enable-maintainer-zts  You'll activate Zend Thread Safety  You only need ZTS is some uncommon specific cases  Take care of "exotic" extensions  They may not be thread-safe themselves  Analyze before using them  Please don't blindly blame PHP
  • 43. Thank you for listening