8

According to Django is synchronous or asynchronous. Django is synchronous. However I tested a blocking view with python manage.py runserver 8100:

    import time
    @action(detail=False, methods=['get'])
    def test(self, request):
        time.sleep(5)
        return {}

and triggered two requests with postman at 0s, 1s, and they returned at 5s, 6s. That seems not blocking/synchronous. Where am I wrong?

YNX
  • 511
  • 6
  • 17
  • 2
    Django (or any other traditional server) uses multithreading to serve multiple requests at the same time. This is called concurrency. Note that concurrent and asynchronous aren't the same things, but they are somewhat similar. – xyres Nov 24 '20 at 05:23
  • @xyres Yeah, I know what you mean. However when my two requests were blocking in the `time.sleep(10)`, `ps -ef |grep runserver` or `ps -ef |grep ${PID}` shows only one process. – YNX Nov 24 '20 at 06:29
  • 1
    A single process can run multiple threads. You're confusing multithreading with multiprocessing. – xyres Nov 24 '20 at 06:46
  • @ xyres I run multiple requests at the same time(within 10s), and display threads tree with htop. It's the same after and before, nothing changes. There is no multithreading. – YNX Nov 24 '20 at 07:55
  • 1
    Probably htop is not showing the threads. But the django dev server is multithreaded. You can see this in the docs: the [`--nothreading`](https://docs.djangoproject.com/en/3.1/ref/django-admin/#cmdoption-runserver-nothreading) argument is used for disabling multithreading. You can also check the source code to confirm that: https://github.com/django/django/blob/master/django/core/servers/basehttp.py – xyres Nov 24 '20 at 08:19
  • how to display threading id ? i use htop with display tree and treading,but still have one threading – Cherrymelon Jun 29 '22 at 18:35

1 Answers1

8

Even synchronous implementations handle usually multiple requests 'in parallel'.

They do so by using multiple processes, multiple threads or a mix of it.

Depending on the server they have a predefined (fixed) amount of processes or threads or they dynamically allocate threads or processes whenever another requests requires one.

An asynchronous server on the other hand can handle multiple requests 'in parallel' within only one thread / process.

The simple development server, that you can start with management.py runserver is using threading by default.

To best visualize this I suggest to change your code to:

import time
import os
import threading

@action(detail=False, methods=['get'])
def test(self, request):
    print("START PID", os.getpid(), "TID", threading.get_native_id())
    time.sleep(5)
    print("STOP  PID", os.getpid(), "TID", threading.get_native_id())
    return {pid=os.getpid(), tid=threading.get_native_id()}

As @xyres mentioned: There is a command line option to disable threading.

Just run manage.py runserver --nothreading and try again. Now you should be able to visualize the full synchronous behavior.

gelonida
  • 5,327
  • 2
  • 23
  • 41