Python 如何组合线程?
我正在尝试在Raspberry Pi上设置一个程序,将温度数据记录到csv作为一个主进程,如果温度超出裕度,并行进程将按时间间隔发送电子邮件通知。我读到可以用Python的线程模块来完成,所以我正在尝试设置一个测试代码,稍后将为传感器优化它。我正在使用random.randrange模块进行虚拟读数,但是温度监控线程无法读取要激活的温度变量。“if”语句如何正确读取变量 我尝试在while-True循环之外设置temp,并在循环之后激活线程Python 如何组合线程?,python,multithreading,Python,Multithreading,我正在尝试在Raspberry Pi上设置一个程序,将温度数据记录到csv作为一个主进程,如果温度超出裕度,并行进程将按时间间隔发送电子邮件通知。我读到可以用Python的线程模块来完成,所以我正在尝试设置一个测试代码,稍后将为传感器优化它。我正在使用random.randrange模块进行虚拟读数,但是温度监控线程无法读取要激活的温度变量。“if”语句如何正确读取变量 我尝试在while-True循环之外设置temp,并在循环之后激活线程 import time import csv impo
import time
import csv
import random
import smtplib
import threading
path = 'C:/Users/saint/.PyCharmCE2019.1/config/scratches/log.csv'
templogfile = open(path,'a')
sender = 'sender@gmail.com'
receivers = ['receiver@hotmail.com']
def send_email():
while True:
print("mail module")
if temp <= 20:
try:
smtpObj = smtplib.SMTP('smtp.gmail.com', 587)
smtpObj.starttls()
smtpObj.login('sender@gmail.com', 'senderpassword')
smtpObj.sendmail(sender, receivers, message)
print("Successfully sent email")
time.sleep(15)
except smtplib.SMTPException:
print("Error: unable to send email")
time.sleep(15)
Threads = []
for i in range(1):
t = threading.Thread(target=send_email)
t.daemon = True
t.start()
with open(path,'a') as csvfile:
tempwriter = csv.writer(csvfile)
tempwriter.writerow(['Time', 'Temperature C'])
while True:
time_now = time.asctime()
temp = random.randrange(-10,20)
tempwriter.writerow([time_now, temp])
templogfile.close()
print('Time:', time_now, 'Temperature:', temp)
csvfile.flush()
time.sleep(5)
导入时间
导入csv
随机输入
导入smtplib
导入线程
路径='C:/Users/saint/.PyCharmCE2019.1/config/scratches/log.csv'
templagfile=open(路径'a')
发送者sender@gmail.com'
接收者=['receiver@hotmail.com']
def send_email():
尽管如此:
打印(“邮件模块”)
如果temp我不确定在这里发送电子邮件是否需要单独的线程。为什么不只是:
def发送电子邮件(临时):
打印(“邮件模块”)
如果temp我不确定在这里发送电子邮件是否需要单独的线程。为什么不只是:
def发送电子邮件(临时):
打印(“邮件模块”)
如果temp如果您的电子邮件发送线程中没有定义temp
的异常,我怀疑这是由于您正在运行的两个线程的计时造成的。如果电子邮件线程在主线程第一次(模拟)读取温度之前运行,temp
变量将不存在。这可能会发生,也可能不会发生,这取决于线程计时的确切细节,这些细节并不总是可预测的(尽管子线程在父线程恢复之前运行一段时间可能非常常见)
有几种方法可以解决这个问题。一个简单的解决方法是在send_email
函数的启动中添加一个延迟,这样运行它的线程将暂停足够长的时间,以便主线程中的温度读数已经启动。只需在while True
循环开始之前添加一行,如sleep(1)
或类似内容
另一个选项是在启动电子邮件线程之前将temp
初始化为某个伪值。这样就可以读取一个变量,即使它实际上并不代表测量(或模拟)的温度。类似于temp=21
的东西放在线程开始循环之前的某个地方就可以实现这一点
但我注意到,在这种情况下使用线程的目的并不十分清楚。电子邮件线程差不多每三分之一的温度读数就进行一次采样,但是如果你想要的话,你可以更明确地这样做。如果你不想以传感器回路的全速发送邮件,你也可以检查每一次读数,并且只以更有限的速率发送电子邮件。我会考虑这样的事情:
email_flag = False
count = 0
while True:
time_now = time.asctime()
temp = random.randrange(-10,20)
tempwriter.writerow([time_now, temp])
if temp <= 20:
email_flag = True
count += 1
if email_flag and count >= 3:
send_email() # unconditionally sends the message
email_flag = False
count = 0
email\u标志=False
计数=0
尽管如此:
time\u now=time.asctime()
温度=随机随机随机范围(-10,20)
tempwriter.writerow([time\u now,temp])
如果温度=3:
send_email()#无条件发送消息
email_flag=False
计数=0
如果您的电子邮件发送线程中未定义temp
的异常,我怀疑这是由于您正在运行的两个线程的计时造成的。如果电子邮件线程在主线程第一次(模拟)读取温度之前运行,temp
变量将不存在。这可能会发生,也可能不会发生,这取决于线程计时的确切细节,这些细节并不总是可预测的(尽管子线程在父线程恢复之前运行一段时间可能非常常见)
有几种方法可以解决这个问题。一个简单的解决方法是在send_email
函数的启动中添加一个延迟,这样运行它的线程将暂停足够长的时间,以便主线程中的温度读数已经启动。只需在while True
循环开始之前添加一行,如sleep(1)
或类似内容
另一个选项是在启动电子邮件线程之前将temp
初始化为某个伪值。这样就可以读取一个变量,即使它实际上并不代表测量(或模拟)的温度。类似于temp=21
的东西放在线程开始循环之前的某个地方就可以实现这一点
但我注意到,在这种情况下使用线程的目的并不十分清楚。电子邮件线程差不多每三分之一的温度读数就进行一次采样,但是如果你想要的话,你可以更明确地这样做。如果你不想以传感器回路的全速发送邮件,你也可以检查每一次读数,并且只以更有限的速率发送电子邮件。我会考虑这样的事情:
email_flag = False
count = 0
while True:
time_now = time.asctime()
temp = random.randrange(-10,20)
tempwriter.writerow([time_now, temp])
if temp <= 20:
email_flag = True
count += 1
if email_flag and count >= 3:
send_email() # unconditionally sends the message
email_flag = False
count = 0
email\u标志=False
计数=0
尽管如此:
time\u now=time.asctime()
温度=随机随机随机范围(-10,20)
tempwriter.writerow([time\u now,temp])
如果温度=3:
send_email()#无条件发送消息
email_flag=False
计数=0
我认为问题在于其中一个线程试图在创建全局temp
变量之前访问该变量。一个非常简单的解决方案是在模块顶部附近创建它,包括:
temp = None
然后向线程函数添加一个短前导,使其等待变量设置为某个值:
def send_email():
# Wait for global to have data (ADDED)
while temp is None:
time.sleep(.5)
while True:
print("mail module")
if temp <= 20:
try:
smtpObj = smtplib.SMTP('smtp.gmail.com', 587)
smtpObj.starttls()
smtpObj.login('sender@gmail.com', 'senderpassword')
smtpObj.sendmail(sender, receivers, message)
print("Successfully sent email")
time.sleep(15)
except smtplib.SMTPException:
print("Error: unable to send email")
time.sleep(15)
def send_email():
#等待全局有数据(已添加)
当temp为“无”时:
时间。睡眠(.5)
尽管如此:
打印(“邮件模块”)
如果temp我认为问题是因为其中一个线程试图在创建全局temp
变量之前访问该变量。一个非常简单的解决方案是在模块顶部附近创建它,并使用: