讲师中心 微信公众号

工具推荐

视频效率加速
updream

一键生成高质量推广成片

Laper
Laper

剧本策划到成片协作

立刻MV
立刻MV

低成本歌曲 MV、视频生成

AniShort
AniShort

AI短剧协同制作平台

保持Python脚本关闭后对象状态的方法

酷婷大大_8181

酷婷大大_8181

发布时间:2025-08-23 16:00:18

|

741人浏览过

|

来源于php中文网

原创

保持python脚本关闭后对象状态的方法

本文旨在解决在LabVIEW调用Python脚本控制电子板时,如何保持电子板对象状态,避免频繁开关串口导致连接问题。文章将探讨通过后台运行脚本或进程,以及在关闭串口前清理缓冲区和增加延时等方法,确保串口连接的稳定性和可靠性。

在LabVIEW等环境中调用Python脚本控制硬件设备,例如电子板时,经常会遇到串口通信的问题。一个常见的场景是,每次调用一个Python脚本,都会初始化电子板对象并打开串口,脚本执行完毕后关闭串口。这种频繁的开关操作可能会导致串口连接不稳定,甚至出现端口占用等问题。本文将介绍几种解决此问题的方法,以确保串口通信的稳定性和可靠性。

方法一:后台运行脚本或进程

一种解决方案是将初始化电子板对象的脚本作为一个独立的进程或服务在后台运行。这样,电子板对象只会被初始化一次,串口也只会被打开一次,避免了频繁的开关操作。

  1. 创建初始化脚本: 创建一个Python脚本,用于初始化电子板对象并保持运行状态。

    立即学习“Python免费学习笔记(深入)”;

    # Set_Board.py
    import time
    import serial
    
    class ElectronicBoard:
        def __init__(self, com_port="COM5", verbose=True):
            self.com_port = com_port
            self.verbose = verbose
            try:
                self.ser = serial.Serial(self.com_port, 9600, timeout=1) # 串口初始化
                self.is_powered = True
                if self.verbose:
                    print("Connected!")
            except serial.SerialException as e:
                self.is_powered = False
                print(f"Connection failed: {e}")
                self.ser = None
    
        def doFunctionX(self):
            if self.ser:
                self.ser.write(b"X")  # 发送指令X
                print("Function X executed")
            else:
                print("Serial port not initialized")
    
        def doFunctionY(self):
            if self.ser:
                self.ser.write(b"Y")  # 发送指令Y
                print("Function Y executed")
            else:
                print("Serial port not initialized")
    
        def close(self):
            if self.ser:
                self.ser.close()
                print("Serial port closed")
            else:
                print("Serial port not initialized")
    
    board = ElectronicBoard(com_port="COM5", verbose=True)
    
    if board.is_powered:
        print("Board initialized and running in the background.")
        while True:
            time.sleep(1)  # 保持脚本运行
    else:
        print("Failed to initialize board.")
  2. 后台运行脚本: 可以使用各种方法在后台运行此脚本,例如使用nohup命令(Linux)或将其转换为Windows服务。

    • Linux (nohup):

      nohup python Set_Board.py &
    • Windows (创建服务): 可以使用pywin32库将Python脚本转换为Windows服务。

      Python Hardener
      Python Hardener

      通过完整的安全审查、代码整洁重构、健壮的错误处理、正确的日志记录以及完整的文档字符串覆盖,强化 Python 脚本。

      下载
  3. 其他脚本调用: 其他脚本可以通过某种进程间通信(IPC)机制与后台运行的脚本进行通信,例如使用套接字、管道或消息队列。

    # Script1.py
    import socket
    
    def send_command(command):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.connect(('localhost', 65432))  # 连接到后台脚本的套接字
            s.sendall(command.encode())
            data = s.recv(1024)
        print(f"Received {data.decode()}")
    
    send_command("doFunctionX")
    # Set_Board.py (修改后的后台脚本)
    import socket
    import threading
    
    # ... (ElectronicBoard 类定义)
    
    board = ElectronicBoard(com_port="COM5", verbose=True)
    
    def handle_connection(conn, addr):
        with conn:
            print(f"Connected by {addr}")
            while True:
                data = conn.recv(1024)
                if not data:
                    break
                command = data.decode()
                print(f"Received command: {command}")
                if command == "doFunctionX":
                    board.doFunctionX()
                    conn.sendall(b"Function X executed")
                elif command == "doFunctionY":
                    board.doFunctionY()
                    conn.sendall(b"Function Y executed")
                else:
                    conn.sendall(b"Unknown command")
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(('localhost', 65432))
        s.listen()
        print("Board initialized and listening for commands.")
        while True:
            conn, addr = s.accept()
            thread = threading.Thread(target=handle_connection, args=(conn, addr))
            thread.start()
    

    注意事项: 需要选择合适的IPC机制,并确保其稳定性和安全性。

方法二:清理缓冲区和增加延时

如果无法使用后台进程,可以尝试在每次关闭串口之前,清理输入和输出缓冲区,并在关闭串口后增加一个延时。

# Script1.py
import serial
import time

try:
    board = serial.Serial("COM5", 9600, timeout=1)
    print("Connected!")
except serial.SerialException as e:
    print(f"Connection failed: {e}")
    board = None

if board:
    board.write(b"X")  # 发送指令X
    print("Function X executed")

    board.flushInput()  # 清理输入缓冲区
    board.flushOutput() # 清理输出缓冲区
    board.close()
    print("Serial port closed")
    time.sleep(2)  # 增加延时 (至少1-2秒)

解释:

  • board.flushInput(): 清空输入缓冲区,丢弃所有未读取的数据。
  • board.flushOutput():清空输出缓冲区,等待所有数据发送完毕。
  • time.sleep(2): 在关闭串口后暂停2秒。这个延时允许操作系统释放串口资源,避免端口被立即占用。

注意事项:

  • 延时时间需要根据实际情况调整。
  • 确保在所有脚本中都使用相同的清理缓冲区和延时策略。

方法三:使用单例模式

可以使用单例模式来确保只有一个电子板对象存在。这样,所有的脚本都使用同一个对象,避免重复初始化和关闭串口。

# ElectronicBoardSingleton.py
import serial

class ElectronicBoard:
    _instance = None

    def __new__(cls, com_port="COM5", verbose=True):
        if cls._instance is None:
            cls._instance = super(ElectronicBoard, cls).__new__(cls)
            cls._instance.com_port = com_port
            cls._instance.verbose = verbose
            try:
                cls._instance.ser = serial.Serial(cls._instance.com_port, 9600, timeout=1)
                cls._instance.is_powered = True
                if cls._instance.verbose:
                    print("Connected!")
            except serial.SerialException as e:
                cls._instance.is_powered = False
                print(f"Connection failed: {e}")
                cls._instance.ser = None
        return cls._instance

    def doFunctionX(self):
        if self.ser:
            self.ser.write(b"X")  # 发送指令X
            print("Function X executed")
        else:
            print("Serial port not initialized")

    def doFunctionY(self):
        if self.ser:
            self.ser.write(b"Y")  # 发送指令Y
            print("Function Y executed")
        else:
            print("Serial port not initialized")

    def close(self):
        if self.ser:
            self.ser.close()
            print("Serial port closed")
            self.ser = None  # 确保下次调用时重新初始化
        else:
            print("Serial port not initialized")
# Script1.py
from ElectronicBoardSingleton import ElectronicBoard

board = ElectronicBoard(com_port="COM5")
board.doFunctionX()
board.close()
# Script2.py
from ElectronicBoardSingleton import ElectronicBoard

board = ElectronicBoard(com_port="COM5")
board.doFunctionY()
board.close()

注意事项:

  • 单例模式确保只有一个对象,但仍然需要在每次脚本结束后关闭串口,并清理缓冲区和增加延时,以避免端口占用问题。
  • 在多线程或多进程环境下使用单例模式需要注意线程安全问题。

总结

本文介绍了三种解决在LabVIEW调用Python脚本控制电子板时,保持电子板对象状态的方法:后台运行脚本或进程、清理缓冲区和增加延时、以及使用单例模式。选择哪种方法取决于具体的应用场景和需求。如果需要频繁地与电子板进行通信,并且对实时性要求较高,建议使用后台运行脚本或进程。如果只是偶尔需要与电子板进行通信,并且可以容忍一定的延时,可以使用清理缓冲区和增加延时的方法。使用单例模式可以确保只有一个电子板对象存在,但仍然需要注意串口资源的释放。 无论选择哪种方法,都需要进行充分的测试,以确保串口通信的稳定性和可靠性。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4758

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

1329

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

443

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

599

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

449

2026.02.06

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

273

2026.03.16

Java 多线程与并发编程实战
Java 多线程与并发编程实战

深入讲解 Java 并发编程体系,涵盖 Thread / Runnable / Callable 线程创建方式、线程生命周期与状态转换、synchronized 同步锁与 Lock/ReentrantLock 显式锁、volatile 可见性保证、ThreadPool 线程池配置与调优(核心参数/拒绝策略)、JUC 并发工具类(CountDownLatch/CyclicBarrier/Semaphore/ConcurrentHashMa

389

2026.04.17

C++ 多线程使用教程大全
C++ 多线程使用教程大全

系统讲解 C++11 及后续标准引入的多线程编程能力,涵盖 std::thread 线程创建与生命周期管理、std::mutex / shared_mutex 互斥锁与读写锁、std::condition_variable 条件变量同步、std::atomic 原子操作与内存序(memory_order)、std::future / promise / async 异步任务、线程池的设计与实现、死锁检测与避免策略,帮助开发者编写正确高效

256

2026.04.28

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

40

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn