2016-10-17 7 views
-1

フラスコサーバーが稼働しており、マルチプロセッシングループが動作しています。私はフラスコサーバーの変数を変更し、ifステートメントのループでそれを見ることができるようにしたい。ここで私のコードですが、私は重要ではないと思ったことを多く削除しました。マルチプロセッシングはefectivelly実行フラスコサーバーとマルチプロセッシングループの間の変数の編集と読み取り

変更する必要がある変数がトグルされ (のみ1または0である必要がある)、それは、SMSに変更されます()とループにおけるif文で使用

# I removed a lot of stuff that i dont think was needed 

import time 
import math 
from pyicloud import PyiCloudService 
import requests.packages.urllib3 
requests.packages.urllib3.disable_warnings() 
from math import sin, cos, sqrt, atan2, radians 
from twilio.rest import TwilioRestClient 
from multiprocessing import Process, Value 
from flask import Flask, request 
from twilio import twiml 
import os 
#os.system('clear') 

app = Flask(__name__) 

sent = 0 #only needed for loop 

toggle = 0 # this is the varable that needs to be changed and viewed 



def distance(x): 
    #returns distance in miles or km 

@app.route('/sms', methods=['POST']) 
def sms(): 
    global toggle 

    #command replys 
    error = 'You did not enter a valid command' 
    on = 'Automatic tracker has been turned on.' 
    already_on = 'The automatic tracker is already on.' 
    off = 'Automatic tracker has been turned off.' 
    already_off = 'The automatic tracker is already off.' 
    toggle_error = 'There was a changing the status automatic tracker.' 
    status0 = 'The automatic tracker is currently off.' 
    status1 = 'The automatic tracker is currently on.' 
    status_error = 'There was a error checking the status of the automatic tracker.' 

    message_body = request.form['Body'] # message you get when sending a text to twilio number ex. i send "On" to the number and message_body will = "On" 
    resp = twiml.Response() # what twilio will send back to your number 

    if message_body == "on" or message_body == "On": #turn on automatic tracker 
     if toggle == 0: #set toggle to 1 
      toggle = 1 
      resp.message(on) 
      print on 
      time.sleep(3) 
     elif toggle == 1: #say toggle is on 
      resp.message(already_on) 
      print already_on 
      time.sleep(3) 
     else: #say toggle_error 
      resp.message(toggle_error) 
      print toggle_error 
      time.sleep(3) 
    elif message_body == "off" or message_body == "Off": #turn off automatic tracker 
     if toggle == 1: #set toggle to 0 
      toggle = 0 
      resp.message(off) 
      print off 
      time.sleep(3) 
     elif toggle == 0: #say toggle is off 
      resp.message(already_off) 
      print already_off 
      time.sleep(3) 
     else: #say toggle_error 
      resp.message(toggle_error) 
      print toggle_error 
      time.sleep(3) 
    elif message_body == "status" or message_body == "Status": #return status of automatic tracker 
     if toggle == 1: #say toggle is on 
      resp.message(status1) 
      print status1 
      time.sleep(3) 
     elif toggle == 0: #say toggle is off 
      resp.message(status0) 
      print status0 
      time.sleep(3) 
     else: #say status_error 
      resp.message(status_error) 
      print status_error 
      time.sleep(3) 
    else: #say invalid command 
     resp.message(error) 
     print error 
     print " " 
     time.sleep(3) 
    return str(resp) 
    print " " 

def record_loop(loop_on): 
    while True: 
     global sent 
     global toggle 
     if toggle == 1: #toggle does not read as 1 when changed in sms() 
      if distance(2) < 2.5: 
       if sent == 0: 
        print "CLOSE" 
        print "sending message" 
        print distance(2) 
        client.messages.create(
        to="phone number to send to", #I removed the 2 numbers 
        from_="twillio number", #I removed the 2 numbers 
        body= "CLOSE!", 
        ) 
        sent = 1 
       else: 
        print "CLOSE" 
        print "not sending" 
        print distance(2) 
      else: 
       print "not close" 
       print distance(2) 
       sent = 0 
     else: 
      print 'toggle is off' 
      print toggle 
     time.sleep(1) 
     print " " 
     time.sleep(20) 

if __name__ == "__main__": 
    recording_on = Value('b', True) 
    p = Process(target=record_loop, args=(recording_on,)) 
    p.start() 
    app.run(use_reloader=False) 
    p.join() 
+3

これを[mcve]に減らしてください。あなたが書いたようにあなたがどんな問題を抱えているのかを明確にするのは本当に難しいことです。プロセスはメモリを共有しないので、グローバルを変更して他のプロセスに影響を与えることはできません。 – davidism

答えて

2

他のプロセスのターゲット関数 - これはまったく新しいPythonプログラムでもあり - この他のプログラムは親プログラムと変数を共有しません。そのため、グローバル変数を使用してセカンダリループと通信する方法は、このようには機能しません。record_loop内の変数toggleは、プログラムのビューで使用される変数とは独立しています。

整形式のアプリケーションでは、multiprocessing.Queueのインスタンスを使用して、別のプロセスの関数で実行中のコードに値を伝達するだけで十分です。

しかし、 "weel behaved"はあなたが持っているものではありません - マルチプロセスの使用.Queueは、元のプロセスが常にサブプロセスと共有される1つのQueueオブジェクトにアクセスできると仮定します。しかし、Flaskアプリケーションを使用しています.FlaskアプリケーションはWSGI Pythonモデルを使用しています。つまり、各HTTP要求処理(つまり、smsビュー呼び出しへの呼び出し)は、コード内の他のすべてのリソースとは独立しています。グローバル変数を含む。これは、WSGIサーバーのコンテキストでは、各HTTP要求が完全に異なる処理(WSGIサーバーの構成によって異なる)によって処理されるためです。

したがって、サーバ側でより長いプロセスをトリガするHTTPリクエストの「現実的な」ケースの場合、最良のアプローチの1つはCeleryを使用することです。 Celeryでは、ワーカーを明示的に起動します。これは、ビューとワーカーコードが同じ.pyファイルにある場合でも、HTTPリクエストに応答するプロセスとは独立して存在します。ビューは透過的な方法でワーカーの関数を呼び出し、別のプロセスで非同期で単純に実行します。

あなたは、一方が他方については何も知らなくても、並行して、あなたのrecord_loopコードを実行しているいくつかのプロセスを持って気にしない場合Queueとマルチプロセスアプローチは、しかし、使用することができます - あなただけのこのコードのリモートAPIをトリガしているので、それは問題ではないように見えます。

関連する問題