Python多线程和共享类对象

发布于 2025-02-13 10:18:42 字数 5007 浏览 0 评论 0原文

我的Python程序有多个线程,它们需要分享(读写)到同一对象。 我遇到问题,有时值正确存储,但是其他线程的更新不够快,只有在第二或第三个交互中,它们已对其进行更新。 这是我的代码:

from flask import Flask, render_template, request, jsonify
import threading
from time import sleep


from gpiozero import LED, Button, DigitalOutputDevice
SUM_ALARM_NC = LED(5)
SUM_ALARM_NO = LED(6)
SUM_ALARM_LED = LED(13)
SUM_ALARM_IN = Button(12)


from dataclasses import dataclass
import string
@dataclass
class Config_File:
    status: string
    serial_interface: string
    changed:string

app = Flask(__name__, static_folder = 'assets')

@app.route("/")
def Index():
    return render_template("index.html")


@app.route("/_monitoring")
def _monitoring():
    return jsonify(_status = Config_File.status.strip(), _serial_interface = Config_File.serial_interface.strip())

#---------------------------------------------------------------------------------------------------------------
@app.route("/_saveserial")
def saveserial():
    Config_File.changed = "1\n"
    Config_File.serial_interface = str(request.args.get('RS232')) + "," + str(request.args.get('baudrate')) + "," + str(request.args.get('parity')) + "," + str(request.args.get('databit')) + "," + str(request.args.get('address'))  + "\n"
    return ""

def Monitoring_IO_thr():
    while (True):
        if SUM_ALARM_IN.is_pressed:
            Config_File.changed = "0\n"
            Config_File.status = "1\n"
            SUM_ALARM_LED.on()
        else:
            Config_File.status = "0\n"
            SUM_ALARM_LED.off()
        sleep(0.5)

#### Save config_file class to the config.ini file ######################
def Save_Config_File_thr():
    while (True):
        if Config_File.changed == "1\n":
            Config_File.changed = "0\n"
            file_read = "config.ini"
            fileobj = open(file_read,'r').readlines()
            fileobj[3]= "Status:"+ Config_File.status
            fileobj[21]= "Serial:" + Config_File.serial_interface
            fileobj[55]= "Changed:" + Config_File.changed
            # writes lines
            with open(file_read,'w') as file:
                file.writelines(fileobj)
            file.close()
        sleep(1)


if __name__ == "__main__":
    Config_File.serial_interface="RS232,9600,Even,7,A\n"
    Monitoring_IO_thread = threading.Thread(target = Monitoring_IO_thr)
    Monitoring_IO_thread.start()
    
    Save_Config_File_thread = threading.Thread(target = Save_Config_File_thr)
    Save_Config_File_thread.start()

    app.run(host='192.168.150.144', port=5050, debug=True)
    
    Monitoring_IO_thread.join()
    Save_Config_File_thread.join()

这是我的脚本

<script>
  $(document).ready(function ()
    {  

    $(function() 
      {
        //SERIAL INTERFACE CHANGE - script to deal with the request to change the serial interface
        $('#saveserial').on('click',function()
          {
            var data =
              {
                RS232: $('#RS232').val(),
                baudrate: $('#baudrate').val(),
                parity: $('#parity').val(),
                databit: $('#databit').val(),
                address: $('#address').val(),
              };
                            $.getJSON("/_saveserial", data, function ()
                                {
                                });
            });     
      });

    $(function monitoring() 
      {
        $.getJSON('/_monitoring', function(data)
          {
            if (data._status == "1")
              {
                $("#alarm_on").attr("hidden", false);
                $("#alarm_off").attr("hidden", true);
              }
            if (data._status == "0")
              {
                $("#alarm_on").attr("hidden", true);
                $("#alarm_off").attr("hidden", false);
              }
            
            setTimeout(function(){monitoring();},500);
            });
      }
    );
  });
  </script>

如何在线程之间共享config_file?

在您宝贵的帮助之后,我尝试了以下内容:

from multiprocessing import Process, Lock
mutex=Lock()

def Monitoring_IO_thr():
    mutex.acquire()
    try:    
        while(True):
            Inputs_Monitoring()
            sleep(0.5)
    finally:
        mutex.release()

def Save_Config_File_thr():
    mutex.acquire()
    try:    
        while(True):
            if Config_File.changed == "1\n":
                Config_File.serial_interface)
                #save to file
                Config_File.changed = "0\n"
                Save_config()
                out("saving config.ini")
            sleep(1)
    finally:
        mutex.release()

if __name__ == "__main__":
    Init()
    app.run(host='192.168.150.144', port=5050, debug=True)

    while(True):
        Monitoring_IO_thread = threading.Thread(target = Monitoring_IO_thr)
        Monitoring_IO_thread.start()
        
        Save_Config_File_thread = threading.Thread(target = Save_Config_File_thr)
        Save_Config_File_thread.start()

不确定为什么但是该程序永远不会运行两个线程...有什么想法我在做什么错?

My python program has several threads and they need to share (read and write) to the same object.
I am having problems, sometimes the value is stored correctly but other threads don't have it updated quick enough and only on a second or third interaction they have it updated.
this is my code:

from flask import Flask, render_template, request, jsonify
import threading
from time import sleep


from gpiozero import LED, Button, DigitalOutputDevice
SUM_ALARM_NC = LED(5)
SUM_ALARM_NO = LED(6)
SUM_ALARM_LED = LED(13)
SUM_ALARM_IN = Button(12)


from dataclasses import dataclass
import string
@dataclass
class Config_File:
    status: string
    serial_interface: string
    changed:string

app = Flask(__name__, static_folder = 'assets')

@app.route("/")
def Index():
    return render_template("index.html")


@app.route("/_monitoring")
def _monitoring():
    return jsonify(_status = Config_File.status.strip(), _serial_interface = Config_File.serial_interface.strip())

#---------------------------------------------------------------------------------------------------------------
@app.route("/_saveserial")
def saveserial():
    Config_File.changed = "1\n"
    Config_File.serial_interface = str(request.args.get('RS232')) + "," + str(request.args.get('baudrate')) + "," + str(request.args.get('parity')) + "," + str(request.args.get('databit')) + "," + str(request.args.get('address'))  + "\n"
    return ""

def Monitoring_IO_thr():
    while (True):
        if SUM_ALARM_IN.is_pressed:
            Config_File.changed = "0\n"
            Config_File.status = "1\n"
            SUM_ALARM_LED.on()
        else:
            Config_File.status = "0\n"
            SUM_ALARM_LED.off()
        sleep(0.5)

#### Save config_file class to the config.ini file ######################
def Save_Config_File_thr():
    while (True):
        if Config_File.changed == "1\n":
            Config_File.changed = "0\n"
            file_read = "config.ini"
            fileobj = open(file_read,'r').readlines()
            fileobj[3]= "Status:"+ Config_File.status
            fileobj[21]= "Serial:" + Config_File.serial_interface
            fileobj[55]= "Changed:" + Config_File.changed
            # writes lines
            with open(file_read,'w') as file:
                file.writelines(fileobj)
            file.close()
        sleep(1)


if __name__ == "__main__":
    Config_File.serial_interface="RS232,9600,Even,7,A\n"
    Monitoring_IO_thread = threading.Thread(target = Monitoring_IO_thr)
    Monitoring_IO_thread.start()
    
    Save_Config_File_thread = threading.Thread(target = Save_Config_File_thr)
    Save_Config_File_thread.start()

    app.run(host='192.168.150.144', port=5050, debug=True)
    
    Monitoring_IO_thread.join()
    Save_Config_File_thread.join()

and this are my scripts

<script>
  $(document).ready(function ()
    {  

    $(function() 
      {
        //SERIAL INTERFACE CHANGE - script to deal with the request to change the serial interface
        $('#saveserial').on('click',function()
          {
            var data =
              {
                RS232: $('#RS232').val(),
                baudrate: $('#baudrate').val(),
                parity: $('#parity').val(),
                databit: $('#databit').val(),
                address: $('#address').val(),
              };
                            $.getJSON("/_saveserial", data, function ()
                                {
                                });
            });     
      });

    $(function monitoring() 
      {
        $.getJSON('/_monitoring', function(data)
          {
            if (data._status == "1")
              {
                $("#alarm_on").attr("hidden", false);
                $("#alarm_off").attr("hidden", true);
              }
            if (data._status == "0")
              {
                $("#alarm_on").attr("hidden", true);
                $("#alarm_off").attr("hidden", false);
              }
            
            setTimeout(function(){monitoring();},500);
            });
      }
    );
  });
  </script>

How can I share Config_File between threads?

After your precious help I tried the following:

from multiprocessing import Process, Lock
mutex=Lock()

def Monitoring_IO_thr():
    mutex.acquire()
    try:    
        while(True):
            Inputs_Monitoring()
            sleep(0.5)
    finally:
        mutex.release()

def Save_Config_File_thr():
    mutex.acquire()
    try:    
        while(True):
            if Config_File.changed == "1\n":
                Config_File.serial_interface)
                #save to file
                Config_File.changed = "0\n"
                Save_config()
                out("saving config.ini")
            sleep(1)
    finally:
        mutex.release()

if __name__ == "__main__":
    Init()
    app.run(host='192.168.150.144', port=5050, debug=True)

    while(True):
        Monitoring_IO_thread = threading.Thread(target = Monitoring_IO_thr)
        Monitoring_IO_thread.start()
        
        Save_Config_File_thread = threading.Thread(target = Save_Config_File_thr)
        Save_Config_File_thread.start()

Not sure why but the program never runs both threads... any ideas what am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文