2013-01-17 16 views
49

मैं फ्लास्क को आज़माने के लिए एक छोटा गेम सर्वर लिखने में व्यस्त हूं। गेम उपयोगकर्ताओं को आरईएसटी के माध्यम से एक एपीआई का खुलासा करता है। उपयोगकर्ताओं के लिए क्रियाएं और क्वेरी डेटा करना आसान है, हालांकि मैं ऐप.रुन() लूप के बाहर गेम गेम इत्यादि अपडेट करने के लिए "गेम वर्ल्ड" की सेवा करना चाहता हूं। यह देखते हुए कि फ्लास्क इतना साफ रूप से कार्यान्वित किया गया है, मुझे पसंद है यह देखने के लिए कि क्या ऐसा करने के लिए एक फ्लास्क तरीका है।मैं फ्लास्क में पृष्ठभूमि थ्रेड कैसे जोड़ सकता हूं?

+0

आपका मतलब फ्लास्क-एडमिन जैसे कुछ है? या यदि आप एक ओआरएम (एसक्यूएल-कीमिया) का उपयोग कर रहे हैं, तो आप डेटाबेस को क्वेरी करने के लिए बस एक नया डीबी सत्र बना सकते हैं भले ही एप्लिकेशन चल रहा हो। – reptilicus

+0

यदि आपको वास्तव में बहुत अधिक गणना करने की आवश्यकता है, तो आप उपप्रोसेसर मॉड्यूल का उपयोग करना चाहेंगे, और अतिरिक्त गणना करने के लिए बस नई प्रक्रियाओं को विकसित कर सकते हैं। – Maus

+0

यह एक योजना है, हालांकि उप प्रक्रिया डेटा संरचनाओं में हेरफेर कर रही है, जिसे आप उजागर फ्लास्क एपीआई के माध्यम से एक्सेस करना और सेट करना चाहते हैं। क्या मैं समस्याओं में भाग नहीं पाऊंगा? – Marinus

उत्तर

43

आपके अतिरिक्त थ्रेड को उसी ऐप से शुरू किया जाना चाहिए जिसे डब्लूएसजीआई सर्वर द्वारा बुलाया जाता है।

नीचे दिया गया उदाहरण पृष्ठभूमि थ्रेड बनाता है जो प्रत्येक 5 सेकंड निष्पादित करता है और डेटा संरचनाओं में हेरफेर करता है जो फ्लास्क रूटेड फ़ंक्शंस के लिए भी उपलब्ध हैं।

import threading 
import atexit 
from flask import Flask 

POOL_TIME = 5 #Seconds 

# variables that are accessible from anywhere 
commonDataStruct = {} 
# lock to control access to variable 
dataLock = threading.Lock() 
# thread handler 
yourThread = threading.Thread() 

def create_app(): 
    app = Flask(__name__) 

    def interrupt(): 
     global yourThread 
     yourThread.cancel() 

    def doStuff(): 
     global commonDataStruct 
     global yourThread 
     with dataLock: 
     # Do your stuff with commonDataStruct Here 

     # Set the next thread to happen 
     yourThread = threading.Timer(POOL_TIME, doStuff,()) 
     yourThread.start() 

    def doStuffStart(): 
     # Do initialisation stuff here 
     global yourThread 
     # Create your thread 
     yourThread = threading.Timer(POOL_TIME, doStuff,()) 
     yourThread.start() 

    # Initiate 
    doStuffStart() 
    # When you kill Flask (SIGTERM), clear the trigger for the next thread 
    atexit.register(interrupt) 
    return app 

app = create_app()   

इस तरह Gunicorn से यह कॉल कुछ के साथ:

gunicorn -b 0.0.0.0:5000 --log-config log.conf --pid=app.pid myfile:app 
+6

मुझे फ्लास्क की ऑटो-रीलोड कार्यक्षमता का उपयोग करते समय समस्याग्रस्त होने के लिए मिला (प्रत्येक रीलोड पर एक नया धागा बनाया गया)। इसे ठीक करने के लिए, मैंने [werkzeug.serving.is_running_from_reloader] (http://werkzeug.pocoo.org/docs/0.10/serving/#werkzeug.serving.is_running_from_reloader) का उपयोग केवल तभी बनाया जब ऐप रीलोडर से नहीं चल रहा हो । – raffomania

+2

@caio यह "डेटा लॉक के साथ" होना चाहिए: ऊपर पूंजी एल। –

+0

यह एक अच्छा समाधान है; मल्टीप्रोसेसिंग या थ्रेडिंग मॉड्यूल का उपयोग करने वाले फ्लास्क ऐप्स से निपटने में मदद करता है। मुझें यह पसंद है। –

3

ऐसा लगता है कि a hackish way to do it है, लेकिन मुझे नहीं लगता कि यह तकनीकी रूप से समर्थित है।

मुझे this answer भी मिला, जो इसके लिए फ्लास्क-सेलेरी का उपयोग करने के बारे में बात करता है।

+1

+1 - अजवाइन या कुछ अन्य कार्य कतार प्रणाली इस तरह की चीज के लिए आदर्श है - आपके पास आमतौर पर धागे या उप-प्रक्रियाओं पर कम नियंत्रण होता है (क्योंकि माता-पिता को बिना किसी सूचना के सर्वर द्वारा काटा जा सकता है)। –

2

शुद्ध धागे या अजवाइन कतार उपयोग करने के अलावा (ध्यान दें कि कुप्पी के अजवाइन नहीं रह गया है आवश्यक है), तो आप भी एक हो सकता था कुप्पी के apscheduler को देखो:

https://github.com/viniciuschiele/flask-apscheduler

एक साधारण उदाहरण https://github.com/viniciuschiele/flask-apscheduler/blob/master/examples/jobs.py से नकल:

from flask import Flask 
from flask_apscheduler import APScheduler 


class Config(object): 
    JOBS = [ 
     { 
      'id': 'job1', 
      'func': 'jobs:job1', 
      'args': (1, 2), 
      'trigger': 'interval', 
      'seconds': 10 
     } 
    ] 

    SCHEDULER_API_ENABLED = True 


def job1(a, b): 
    print(str(a) + ' ' + str(b)) 

if __name__ == '__main__': 
    app = Flask(__name__) 
    app.config.from_object(Config()) 

    scheduler = APScheduler() 
    # it is also possible to enable the API directly 
    # scheduler.api_enabled = True 
    scheduler.init_app(app) 
    scheduler.start() 

    app.run() 
संबंधित मुद्दे