简体   繁体   English

如何每隔n秒执行某件事,同时使用Python做其他事情

[英]How to do something every n seconds while doing something else with Python

I'm doing this on a raspberry pi. 我在树莓派上这样做。 I'm very new to python I recently moved from arduino to raspberry for this project. 我是python的新手,我最近从arduino移到了raspberry进行此项目。

I want to send temp to db every 5 seconds but I want to update the graph every 1 minute. 我想每5秒向数据库发送一次temp,但我想每1分钟更新一次图表。 However, the graph doesn't update it gets stuck in writeLog. 但是,该图不会更新,它卡在writeLog中。 I wrote print "loop" after s.run but it doesn't show. 我在s.run之后写了print“ loop”,但是没有显示。 Next I wrote print "here" after s.enter() in writeLog and it shows. 接下来,我在writeLog的s.enter()之后写了print“ here”,它显示了。

Also I couldn't place plotNow inside sched (Error not in main loop). 我也不能将plotNow放在sched内(错误不在主循环中)。 I tried threading but I couldn't get 60sec for the loop. 我尝试了线程化,但无法获得60秒的循环时间。

Here's my current code: 这是我当前的代码:

from matplotlib import pyplot as plt
from datetime import datetime

import MySQLdb
import sched, time

s = sched.scheduler(time.time, time.sleep)

db = MySQLdb.connect(host="localhost", user="root", passwd="", db="log")
cur = db.cursor()

cnt = 0    

tempC = []

plt.ion()
plt.figure(figsize=(10,5))


def writeLog(sc):
    print "Insert to DB"
    try:
        st = "%.2f" % thermoTempC        
        cur.execute("""INSERT INTO history (Datetime, Temp_Degrees, Remarks) VALUES (%s, %s, %s)""", (datetime.now().strftime('%Y-%m-%d %H:%M:%S'), st, 'OK'))
        db.commit()
    except:
        db.rollback()
    s.enter(5,1,writeLog,(sc,))    


def plotNow():
    plt.clf()
    plt.grid(True)        
    plt.title('Current Temp = {:.2f}$^\circ$C'.format(thermoTempC), fontsize=15)   
    plt.ylabel('Temperature(C)')
    plt.xlabel('Time(min)')
    plt.xlim(0,120)
    plt.ylim(0,90)    
    plt.plot(tempC, 'r.-', label='Actual', color='red')
    plt.legend(loc='upper right')   
    plt.show(block=False)


while True:            
    thermoTempC = "32.00"

    tempC.append(thermoTempC)    
    plotNow()
    plt.pause(.1)
    cnt = cnt+1

    if(cnt>120):
        tempC.pop(0)    

    s.enter(5,1,writeLog,(s,))
    s.run()

I couldn't find the duplicate-ish question I was looking for, so here is my answer. 我找不到我要找的重复的问题,所以这是我的答案。

You can put each of your processes in a thread, using the threading module. 您可以使用threading模块将每个进程放入一个线程中。

Let's say you have a send_temp_db and a update_graph functions, which respectively perform the elementary action of sending the temperature once, and updating the graph once. 假设您有send_temp_dbupdate_graph函数,它们分别执行一次发送温度和一次更新图形的基本操作。

You'll need to define two functions that will run continuously: 您需要定义两个可以连续运行的功能:

def send_temp_loop():
    while True:
        send_temp_db(...)
        time.sleep(5)   # wait for 5s

def update_graph_loop():
    while True:
        update_graph(...)
        time.sleep(60)  # wait for 60s

Then, create one thread for both actions, and run the two threads. 然后,为两个操作创建一个线程,然后运行两个线程。

thread_temp = threading.Thread(target=send_temp_loop)
thread_graph = threading.Thread(target=update_graph_loop)

thread_temp.start()
thread_graph.start()

thread_temp.join()

Don't forget to join one of your threads. 不要忘了加入您的线程之一。 If you don't, the program will exit right after the two threads start. 如果您不这样做,程序将在两个线程启动后立即退出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM