Python 如何组合线程?

Python 如何组合线程?,python,multithreading,Python,Multithreading,我正在尝试在Raspberry Pi上设置一个程序,将温度数据记录到csv作为一个主进程,如果温度超出裕度,并行进程将按时间间隔发送电子邮件通知。我读到可以用Python的线程模块来完成,所以我正在尝试设置一个测试代码,稍后将为传感器优化它。我正在使用random.randrange模块进行虚拟读数,但是温度监控线程无法读取要激活的温度变量。“if”语句如何正确读取变量 我尝试在while-True循环之外设置temp,并在循环之后激活线程 import time import csv impo

我正在尝试在Raspberry Pi上设置一个程序,将温度数据记录到csv作为一个主进程,如果温度超出裕度,并行进程将按时间间隔发送电子邮件通知。我读到可以用Python的线程模块来完成,所以我正在尝试设置一个测试代码,稍后将为传感器优化它。我正在使用random.randrange模块进行虚拟读数,但是温度监控线程无法读取要激活的温度变量。“if”语句如何正确读取变量

我尝试在while-True循环之外设置temp,并在循环之后激活线程

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
变量之前访问该变量。一个非常简单的解决方案是在模块顶部附近创建它,并使用: