How does multi threading work in python if GIL locks everything? TL;DR: The trick is when the GIL actually holds the lock and when it lets go. Our code usually does two kind of tasks - 1. CPU-bound (thinking) - Heavy stuff like parsing large JSON, resizing images. This needs the GIL. 2. I/O-bound (waiting) - Waiting for a database, an API call, S3, etc. This does not need the GIL. How it works in Python? Lets take an example of a thread making an API call using requests.get(). -> Python sends the request -> Now it’s just waiting to get a response. At this point, Python knows there’s nothing to “compute”, so it releases the GIL automatically. While Thread A is waiting on the network, Thread B can takeover the GIL and handle another user request. When the response comes, thread A reacquires the GIL, parses the response and completes the API call. This is why Django, Flask, and FastAPI servers can handle hundreds of requests at once. Fun fact - In a typical web request: ~90% of the time is spent waiting (DB, APIs, storage) ~10% is actual computation The GIL makes Python slower for heavy computation. But in most backend systems, database query is usually much slower than any GIL switching delay. Have you ever actually hit a performance issue where the GIL was the real problem? I am trying to learn Python Internals in detail and will share my learnings. Do follow along and tell your experiences in comments. #Python #PythonInternals #SoftwareEngineering #BackendDevelopment
Python GIL: Understanding Locking and Performance
More Relevant Posts
-
🐍 Ever wondered how Python actually works behind the scenes? We write Python like this: print("Hello World") And it just… works 🤯 But there’s a LOT happening in the background. Let me break it down simply 👇 🧠 Step 1: Python compiles your code Your .py file is NOT run directly. Python first converts it into: ➡️ Bytecode (.pyc) This is a low-level instruction format, not machine code yet. ⚙️ Step 2: Python Virtual Machine (PVM) The bytecode is executed by the PVM. Think of PVM as: 👉 Python’s engine that runs your code line by line This is why Python is called: 🟡 An interpreted language (with a twist) 🧩 Step 3: Memory & objects Everything in Python is an object. • Integers • Strings • Functions • Even classes Variables don’t store values. They store references 🔗 That’s why: a = b = 10 points to the SAME object. ⚠️ Step 4: Global Interpreter Lock (GIL) Only ONE thread executes Python bytecode at a time 😐 ✔ Simple memory management ❌ Limits CPU-bound multithreading That’s why: • Python shines in I/O • Struggles with heavy CPU tasks 💡 Why this matters Understanding this helped me: ✨ Debug performance issues ✨ Choose multiprocessing over threads ✨ Write better, scalable backend code Python feels simple on the surface. But it’s doing serious work underneath. Once you know this, Python stops feeling “magic” and starts feeling **powerful** 🚀 #Python #BackendDevelopment #SoftwareEngineering #HowItWorks #DeveloperLearning #ProgrammingConcepts #TechExplained
To view or add a comment, sign in
-
-
Ever felt like you're playing "spot the bug" in your own Python code? 🕵️♂️ Sometimes, the simplest patterns can become the biggest headaches. We often see developers using multiple `if/elif/else` statements for a single variable's value to determine an action or return a specific result. This approach quickly becomes unwieldy. Each new condition adds another layer of indentation and complexity, making the code harder to read, debug, and extend. Imagine adding a fifth or sixth state! Instead, consider using a **dictionary for dispatching actions or values**. This effectively maps states to their corresponding functions or results, making your code much flatter and more explicit. # Bad: def get_user_status_message(status_code): if status_code == 0: return "User is offline" elif status_code == 1: return "User is online" elif status_code == 2: return "User is away" else: return "Unknown status" # Good: STATUS_MESSAGES = { 0: "User is offline", 1: "User is online", 2: "User is away" } def get_user_status_message_clean(status_code): return STATUS_MESSAGES.get(status_code, "Unknown status") ``` The dictionary approach not only improves readability but also makes adding new status messages trivial, without altering the `get_user_status_message_clean` function itself. What's your go-to pattern for handling multiple conditional states in Python? Share your tips! #Python #CleanCode #PythonTips #SoftwareDevelopment #CodingBestPractices #Refactoring #DevTips
To view or add a comment, sign in
-
Python GIL explained in simple words Python has something called the Global Interpreter Lock (GIL). It means: only one thread can execute Python code at a time inside a single process. Now, why does Python do this? 🧠 The reason Python manages memory automatically (garbage collection, reference counting). If multiple threads modified memory at the same time, it could cause crashes and corrupted data. So the GIL: Protects memory Keeps Python simple and stable Makes single-thread execution very fast Yes, this safety comes with extra memory overhead, because Python needs bookkeeping to manage threads safely. ⚡ What about performance? Here’s the important part many people miss: I/O-bound tasks (API calls, database queries, file reads): 👉 Performance is excellent because threads release the GIL while waiting. CPU-bound tasks (heavy calculations, loops): 👉 Threads won’t scale — but Python gives alternatives: Multiprocessing Async programming Native extensions (C/C++) ✅ The takeaway The GIL is not a performance bug. It’s a design trade-off: Slight memory overhead In exchange for simplicity, safety, and great real-world performance Most backend systems are I/O-heavy — and for those, Python performs just fine 🚀 #Python #GIL #Concurrency #BackendEngineering #SoftwareDevelopment
To view or add a comment, sign in
-
Dataclasses in Python: ClassVar, InitVar, slots, cached_property power tools with sharp edges ⚠️ I recently walked through this User dataclass and it’s a perfect example of how modern Python (2024/2025) gives us huge power but also demands clear intent. @dataclass(frozen=False, slots=True) class User: ... This single line already tells a story: slots=True → memory-efficient, faster attribute access frozen=False → this is an entity, not a value object (it can change) 🧠 Key lessons hidden in this code 1️⃣ ClassVar is NOT instance state MAX_LOGIN_ATTEMPTS: ClassVar[int] = 5 This: Does NOT appear in __init__ Does NOT affect equality Is shared across all users 👉 Perfect for constants, limits, and rules not object identity. 2️⃣ InitVar is for construction only password_raw: InitVar[str | None] = None This value: Exists only during initialization Is passed to __post_init__ Is never stored on the object 👉 Ideal for passwords, secrets, or temporary setup data. 3️⃣ slots=True means no dynamic attributes Because of this line: _hashed_password: int | None = field(init=False, repr=False) We explicitly declare internal state. Without it, setting _hashed_password would crash at runtime. 👉 With slots, every attribute must be intentional. 4️⃣ cached_property + mutability = responsibility @cached_property def display_name(self): ... This caches the value after first access. But since frozen=False, this is now possible: user.username = "new_name" 👉 Which means your cache can lie if you mutate fields carelessly. Caching + mutable objects = your responsibility. 5️⃣ Why frozen=False matters here If this were frozen=True: __post_init__ mutation would fail cached_property would break You’d need object.__setattr__ #Python #PythonDataclasses #SoftwareEngineering #BackendDevelopment #CleanCode #Architecture #DesignPatterns #PythonTips #SeniorEngineers
To view or add a comment, sign in
-
-
🐍 A Python mistake that looks innocent… but bites HARD 👇 Common misconception: «“This creates a 3×3 grid.”» grid = [[0] * 3] * 3 Looks fine, right? Most beginners (and many intermediates) think this makes 3 separate rows. ❌ It doesn’t. What actually happens (easy explanation): Python doesn’t copy the inner list. It copies the reference. So all rows point to the same list. Watch this 👀 grid[0][0] = 1 print(grid) Output: [[1, 0, 0], [1, 0, 0], [1, 0, 0]] 😱 Why did all rows change? Because Python didn’t create 3 rows — it created 1 row, reused 3 times. ✅ The correct way: grid = [[0] * 3 for _ in range(3)] Now each row is truly independent. This single concept explains a ton of “Python is acting weird” moments. If you like clear, bite-sized Python lessons that explain why things behave this way — 👉 Get one daily in your inbox: https://lnkd.in/dVNDF-xw One idea. One email. Zero overwhelm 🐍
To view or add a comment, sign in
-
Day 2🚀 When working with Python, data rarely comes in the format we need. Numbers may arrive as strings, decimals may need to become integers, and sometimes values must simply be displayed as text. This is where data type conversion (type casting) becomes essential. Python provides built-in functions like int(), float(), and str() to convert data from one type to another. ✨Float conversion is more flexible. Python allows both whole numbers and decimal values, even when they are stored as strings, to be converted into floating-point numbers. However, non-numeric strings cannot be converted into numbers at all and result in runtime errors. ✨String conversion is the safest of all. Any value — whether a number, decimal, or word — can be converted into a string without errors. #Python #DataScience #TypeCasting #PythonBasics #LearningInPublic #InternshipJourney
To view or add a comment, sign in
-
-
Day 36 – Hash Tables in Python (What’s really behind dict) 🐍 Today, we’re starting with Hash Tables — the idea behind one of Python’s most-used tools: the dict. If you’ve ever written: user = {"name": "John", "age": 25} then you’ve already used a hash table (even if you didn’t realize it). So why start here? Because hash tables help us store and retrieve data fast. Instead of looping through a list item by item, we can jump straight to what we need. That’s why they show up everywhere: user profiles settings and configurations caching quick lookups in real applications Why Python? Python makes this concept very approachable. Dictionaries look simple on the surface, but there’s a lot of smart engineering underneath. Once you understand how they work, you stop writing “just working” code and start writing efficient, intentional code. And yes — this matters for full-stack development too: Backends use hash tables to manage users, sessions, and data Frontends rely on key-value structures for state and UI logic Performance often comes down to how well you organize and access data We’re starting here because this is foundational. When this clicks, many other data structures and algorithms start to make sense. More coming from tomorrow — challenges, breakdowns, and practical thinking. 🚀 #Day36 #Python #DataStructures #HashTables #SoftwareEngineering #FullStackDevelopment #LearningInPublic
To view or add a comment, sign in
-
Why it took nearly 30 years to have no-GIL Python versions? TL;DR: The Single-Thread Tax In the past, every time someone tried to remove the GIL, the standard Python code got 30-50% slower for making refcounting thread safe. How was this solved in Python 3.13+ versions? The move to No-GIL isn't just about deleting the lock. It’s about Biased Reference Counting and Immortal Objects. -> Immortal Objects: Things like True, False and None now have a special status where their reference counter never changes. This means threads don't have to fight over them. So single thread tax is out of question. -> Biased Counting: Python now assumes that the thread that created an object is the one that will use it most. It handles that thread’s counting differently than other(guest) threads. So this finally reached a point where the "Single-Thread Tax" is down to about 5-10%. This approach has real limitations (especially for cross-thread sharing). Will discuss them in next posts. I am trying to learn Python Internals in detail and will share my learnings. Do follow along and tell your experiences in comments. #Python #PythonInternals #SoftwareEngineering #BackendDevelopment
To view or add a comment, sign in
-
-
We often rely heavily on Python’s built-in list (which is actually a dynamic array). But understanding the underlying logic of a Linked List is crucial for mastering Data Structures and Algorithms. Imagine a treasure hunt. 🗺️ Arrays (Python Lists): Are like houses in a row. You know exactly where address #5 is. Linked Lists: Are like clues. You have the first clue, and it points you to the location of the next one. You can't skip ahead; you have to follow the chain. The Python Implementation: It all starts with a single Node. class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def append(self, data): new_node = Node(data) if not self.head: self.head = new_node return last = self.head while last.next: last = last.next last.next = new_node If you need a production-ready Linked List in Python, look no further than collections.deque. It’s implemented as a doubly linked list under the hood! Efficiency! Insertion at the beginning: O(1) for Linked Lists (Instant). Insertion at the beginning: O(n) for Python Lists (Requires shifting every element). #Python #DataStructures #Coding #SoftwareEngineering #Algorithms #Basics
To view or add a comment, sign in
-
TL;DR: Data-Driven SIMCA is now available as a Python package. Check all the details here: https://lnkd.in/ejWzeFz7 During the Christmas break, I worked on a paper where, among other methods, I used Variational Autoencoders and DD-SIMCA. Since Python is the natural choice for ANN-based modeling, I decided to implement the DD-SIMCA routines in Python as well, keeping everything in one place and producing plots with a consistent style. After that, I polished the code and released it as a separate package. The package provides the same functionality as our DD-SIMCA web application (https://mda.tools/ddsimca), which serves as both our baseline and frontrunner. You can obtain the same outcomes and plots, but directly in Python. The repository description contains all the necessary information, including a link to a demo notebook with a code example. The notebook is based on our open access DD-SIMCA tutorial paper (https://lnkd.in/gZjJkU_G).
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development