无法在flask和线程之间共享变量

时间:2019-05-01 13:02:09

标签: python multithreading flask global-variables

我想通过网站(html,js)向用户提供操作。客户端(python)连接到服务器(python),并等待转换/替换/删除文件或目录的请求(python)。

我编写了以下代码,将操作从flask传递到管道PIPE_WEBSERVER,该管道会将其转发到主线程,再将其转发到客户线程,该客户线程会将其发送给客户端。

我实现了libmessage.pylibcon.py来处理所有烦人的零散数据包和内容。

#!/usr/bin/env python3

import socket
import selectors
import threading
import multiprocessing
import time
from flask import Flask, request

import libcon
import libmessage

CON_THREAD_LIST = []
PIPE_WEBSERVER = None

myThread = threading.Thread()

def flask_server():
    app = Flask(__name__)

    def sever_thread_func():
        sel = selectors.DefaultSelector()
        host, port = '', int('65432') # should be replaced by config file
        listen_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        listen_sock.bind((host, port))
        listen_sock.listen()
        print("listening on", (host, port))

        global PIPE_WEBSERVER
        global CON_THREAD_LIST
        PIPE_WEBSERVER, pipe_thread = multiprocessing.Pipe()

        sel.register(listen_sock, selectors.EVENT_READ, data=None)
        sel.register(pipe_thread, selectors.EVENT_READ, data=None)

        while True:
            events = sel.select(timeout=None)
            for key, mask in events:
                if key.fileobj == pipe_thread:
                    request_message = pipe_thread.recv()
                    #next step: deliver to correct conection-thread by iterate through CON_THREAD_LIST
                    found = False
                    for con in CON_THREAD_LIST:
                        if request_message['addr'] == con['addr']:
                            found = True
                            con['pipe'].send(request_message)
                            response_message = con['pipe'].recv()

                    if not found:
                        response_message = libmessage.Message.create_request('status', 'invalid addr')

                    pipe_thread.send(response_message)
                elif key.fileobj == listen_sock:
                    con_sock, addr = listen_sock.accept()
                    print("accepted connection from ", addr)

                    pipe_parent, pipe_child = multiprocessing.Pipe()
                    new_thread = threading.Thread(target=libcon.create_connection_sock,
                                                  args=(con_sock, addr, pipe_child))
                    new_thread.start()
                    thread_infos = {'thread': new_thread,
                                    'pipe' : pipe_parent,
                                    'addr' : addr[0]}
                    CON_THREAD_LIST.append(thread_infos)
                    sel.register(pipe_parent, selectors.EVENT_READ, data=thread_infos)
                else:
                    client_thread = key.data
                    if client_thread in CON_THREAD_LIST:
                        sel.unregister(key.fileobj)
                        CON_THREAD_LIST.remove(client_thread)

            print('CON_THREAD_LIST_t-ID: ' + hex(id(CON_THREAD_LIST)))
            print('Threads in list: ' + str(len(CON_THREAD_LIST)))
            threads_to_remove = []
            for client_info in CON_THREAD_LIST:
                res_running = client_info['thread'].is_alive()
                print('is thread to ' + client_info['addr'] + ' running? : ' + str(res_running))
                if not res_running:
                    threads_to_remove.append()

            for thread_to_remove in threads_to_remove:
                CON_THREAD_LIST.remove(thread_to_remove)


            print('active threads: ' + str(threading.active_count()))


    myThread = threading.Timer(1, sever_thread_func, args=())
    myThread.start()

    time.sleep(0.1) #not quite sure why needed


    print('try to start my stuff -------------')
    return app

app = flask_server()
print('started server')

@app.route('/testHello/test')
def get_my_files():
    name = request.args.get('name')
    #addr = request.args.get('addr')
    addr = '192.168.1.17'
    message = libmessage.Message.create_request('list_files', name, addr)
    PIPE_WEBSERVER.send(message)
    sel_request = selectors.DefaultSelector()
    sel_request.register(PIPE_WEBSERVER, selectors.EVENT_READ, data=None)
    events = sel_request.select(timeout=None)

    for key, mask in events:
        if key.fileobj == PIPE_WEBSERVER:
            result = PIPE_WEBSERVER.recv()
            print(result)

    return result['result']

@app.route('/testHello/connected')
def say_connected_clients():
    global CON_THREAD_LIST
    print('CON_THREAD_LIST_f-ID: ' + hex(id(CON_THREAD_LIST)))
    result = ''
    result += str(len(CON_THREAD_LIST))

    return result

我的问题是CON_THREAD_LIST中的say_connected_clients具有相同的ID,但是我没有相同的元素。但是,当我打电话给http://localhost/testHello/test时,我会从客户ergo PIPE_WEBSERVER那里获得列表。

我知道线程的常见问题(互斥体,锁,线程安全等),但是在这一年龄段,我不确定真正的问题是什么。我只想使用管道通过一个应用程序以短方式处理它。

有人可以为我提供一个真正好用的烧瓶和Python解决方案吗?

0 个答案:

没有答案