Day 28

Day 28

Semaphore objects

This is one of the oldest synchronization primitives in the history of computer science,

A semaphore manages an internal counter which is decremented by each acquire() call and incremented by each release() call. The counter can never go below zero; when acquire() finds that it is zero, it blocks, waiting until some other thread calls release().

There are many cases we may want to allow more than one worker access to a resource while still limiting the overall number of accesses.

For example, we may want to use semaphore in a situation where we need to support concurrent connections/downloads. Semaphores are also often used to guard resources with limited capacity, for example, a database server.There are many cases we may want to allow more than one worker access to a resource while still limiting the overall number of accesses.

For example, we may want to use semaphore in a situation where we need to support concurrent connections/downloads. Semaphores are also often used to guard resources with limited capacity, for example, a database server.

Deadlocks

Multithread programs – Due to the threads that keep on attempting to get multiple locks at once, these are very much prone有倾向的 to deadlocks. Understanding it with an example – a lock is already been acquired by a thread and then a second lock is attempted by the block then in that case, the program can freeze as the thread can potentially block the progress of other threads.

Solution:

  • Enforcement of ordering rule

  • Assigning each lock in a unique manner to the program.

  • Only allowing multiple locks to be acquired in ascending上升 order.

Event Objects

Event object is one of the simplest mechanisms for communication between threads: one thread signals an event and other threads wait for it

We're using multiple threads to spin separate operations off to run concurrently, however, there are times when it is important to be able to synchronize two or more threads' operations. Using Event objects is the simple way to communicate between threads.

An Event manages an internal flag that callers can either set() or clear(). Other threads can wait() for the flag to be set(). Note that the wait() method blocks until the flag is true.

GIL

The Python Global Interpreter Lock or GIL, in simple words, is a mutex (or a lock) that allows only one thread to hold the control of the Python interpreter.

This means that only one thread can be in a state of execution at any point in time. The impact of the GIL isn’t visible to developers who execute single-threaded programs, but it can be a performance bottleneck in CPU-bound and multi-threaded code.

Since the GIL allows only one thread to execute at a time even in a multi-threaded architecture with more than one CPU core, the GIL has gained a reputation as an “infamous” feature of Python.

What Problem Did the GIL Solve for Python?

Python uses reference counting for memory management. It means that objects created in Python have a reference count variable that keeps track of the number of references that point to the object. When this count reaches zero, the memory occupied by the object is released.

The Impact on Multi-Threaded Python Programs

When you look at a typical Python program—or any computer program for that matter—there’s a difference between those that are CPU-bound in their performance and those that are I/O-bound.

CPU-bound programs are those that are pushing the CPU to its limit. This includes programs that do mathematical computations like matrix multiplications, searching, image processing, etc.

I/O-bound programs are the ones that spend time waiting for Input/Output which can come from a user, file, database, network, etc. I/O-bound programs sometimes have to wait for a significant amount of time till they get what they need from the source due to the fact that the source may need to do its own processing before the input/output is ready, for example, a user thinking about what to enter into an input prompt or a database query running in its own process.

Why Hasn’t the GIL Been Removed Yet?

The developers of Python receive a lot of complaints regarding this but a language as popular as Python cannot bring a change as significant as the removal of GIL without causing backward incompatibility issues.

The GIL can obviously be removed and this has been done multiple times in the past by the developers and researchers but all those attempts broke the existing C extensions which depend heavily on the solution that the GIL provides.

Of course, there are other solutions to the problem that the GIL solves but some of them decrease the performance of single-threaded and multi-threaded I/O-bound programs and some of them are just too difficult. After all, you wouldn’t want your existing Python programs to run slower after a new version comes out, right?

How to Deal With Python’s GIL

If the GIL is causing you problems, here a few approaches you can try:

Multi-processing vs multi-threading: The most popular way is to use a multi-processing approach where you use multiple processes instead of threads. Each Python process gets its own Python interpreter and memory space so the GIL won’t be a problem.

原文地址:https://www.cnblogs.com/fengshili666/p/14323402.html