1
from flask import Flask
app = Flask(__name__)


import threading


class SThread(threading.Thread):

    def __init__(self):

        threading.Thread.__init__(self)


    def run(self):

        for i in range(1, 1000):
            print 0


t = SThread()
t.start()


for i in range(1, 1000):
    print 1 

t.join()

@app.route('/')
def hello_world():
    return 'Hello, World!'

When you start your server like this, gunicorn run:app -b 0.0.0.0:8000, you will see all 0s and 1s will be in random order, main thread and child thread are running parallel.

But when you run same piece of code with gunicorn --worker-class eventlet run:app -b 0.0.0.0:8000, you will see first there will be all 0s and then there will be all 1s. That means main thread and child thread are not running parallel.

Is this expected behaviour?
And how can I use eventlet and make use of threading behaviour?

Edited ::

Based on suggestion, I am trying to do something like this to achieve threads like random behaviour and to join these multiple execution streams. But it is running in sequential manner only.

    from flask import Flask
    app = Flask(__name__)


    import eventlet


    def background(): 
        for i in range(1, 10000):
            print 0
        return 42

    def callback(gt, *args, **kwargs): 
        result = gt.wait() 
        print("[cb] %s" % result) 


    greenth = eventlet.spawn(background) 

    for i in range(1, 10000):
        print 1 

    greenth.link(callback)

    @app.route('/')
    def hello_world():
        return 'Hello, World!'
yogesh
  • 33
  • 1
  • 7

1 Answers1

0

This "tight loop" doesn't give chance to run other green threads.

    for i in range(1, 1000):
        print 0

Eventlet / gevent / asyncio / other similar technologies provide cooperative multithreading. So you must write code that cooperates. You may find this answer useful https://stackoverflow.com/a/14227272/73957

In more "real code", you'd perform some network IO or wait on synchronisation which would run other green threads implicitly. Otherwise you need to yield control to other green threads explicitly: eventlet.sleep()

Unwanted code review: it would help if you decided to use one of eventlet or threading.

temoto
  • 5,394
  • 3
  • 34
  • 50
  • thanks for answer, I have added 't.join()' in current question. I have to synchronise these 2 execution streams, can you tell me how can I achieve this behaviour with eventlet, can you provide a code snippet for the same. and thanks for pointing out. actually for loop number printing is just a placeholder for IO task, actually I am doing IO task. @temoto – yogesh Jul 17 '18 at 07:27
  • Eventlet API to spawn green threads in unlimited manner: `eventlet.spawn(func)`, with limit: `GreenPool`. http://eventlet.net/doc/basic_usage.html With IO task instead of print it should just work as expected. – temoto Jul 18 '18 at 17:30
  • if it is fine by you, I can share code sample with you on your email? can you share your email? @temoto – yogesh Jul 19 '18 at 12:11
  • @yogesh yes no problem it's public temotor@gmail.com – temoto Jul 20 '18 at 12:56