gpt4 book ai didi

database - 恢复程序的最后状态

转载 作者:搜寻专家 更新时间:2023-10-30 20:52:20 25 4
gpt4 key购买 nike

我想开发一个程序,它可以恢复使用 sqlite3 数据库的程序中的最后一个循环。

我有一个 Raspberry Pi 运行,源代码是 Python,系统可能会断电并重新启动一段时间。

程序可以从开机启动,但很难回到程序的最后一个循环。让我们将 print 函数视为 Python 语法,每个延迟 5 秒,这意味着有 4 个不同的程序同步运行。

下面的程序没有按预期运行,有人可以帮我解决这个难题吗?

import thread
import time

import sqlite3


conn = sqlite3.connect('testdatabase.db')
conn.isolation_level = None
c = conn.cursor()
c.execute("SELECT ID from LAST_STATE")
fetch=c.fetchone()

def morning_u():
conn = sqlite3.connect('testdatabase.db')
c = conn.cursor()
c.execute("UPDATE LAST_STATE SET ID=1")
conn.commit()
c.close()
conn.close()

def noon_u():
conn = sqlite3.connect('testdatabase.db')
c = conn.cursor()
c.execute("UPDATE LAST_STATE SET ID=2")
conn.commit()
c.close()
conn.close()

def afternoon_u():
conn = sqlite3.connect('testdatabase.db')
c = conn.cursor()
c.execute("UPDATE LAST_STATE SET ID=3")
conn.commit()
c.close()
conn.close()

def evening_u():
conn = sqlite3.connect('testdatabase.db')
c = conn.cursor()
c.execute("UPDATE LAST_STATE SET ID=4")
conn.commit()
c.close()
conn.close()

def morning():
print ("morning")
time.sleep(5)
return

def noon():
print ("noon")
time.sleep(5)
return

def afternoon():
print ("afternoon")
time.sleep(5)


def evening():
print ("evening")
time.sleep(5)
morning_u()

while True:
if fetch[0] is 1:
morning()
noon_u()
if fetch[0] is 2:
noon()
afternoon_u()
if fetch[0] is 3:
afternoon()
evening_u()
if fetch[0] is 4:
evening()
morning_u()

数据库信息

conn = sqlite3.connect('testdatabase.db')

conn.execute('''CREATE TABLE LAST_STATE
(ID INT PRIMARY KEY NOT NULL);''')

conn.execute("INSERT INTO LAST_STATE (ID) \
VALUES (1)");

根据评论编辑程序,请提出改进​​意见

import datetime
import time
import logging
import sqlite3


conn = sqlite3.connect('testdatabase.db')
conn.isolation_level = "IMMEDIATE"
c = conn.cursor()
c.execute("SELECT ID from LAST_STATE")
state=c.fetchone()

def morning_u():
c.execute("UPDATE LAST_STATE SET ID=1")
conn.commit()

def noon_u():
c.execute("UPDATE LAST_STATE SET ID=2")
conn.commit()

def afternoon_u():
c.execute("UPDATE LAST_STATE SET ID=3")
conn.commit()

def evening_u():
c.execute("UPDATE LAST_STATE SET ID=4")
conn.commit()

def morning():
print ("morning")
time.sleep(5)

def noon():
print ("noon")
time.sleep(5)

def afternoon():
print ("afternoon")
time.sleep(5)

def evening():
print ("evening")
time.sleep(5)

while True:
if state[0] is 1:
morning()
try:
noon_u()
except:
print ("error1")

if state[0] is 2:
noon()
try:
afternoon_u()
except:
print ("error2")

if state[0] is 3:
afternoon()
try:
evening_u()
except:
print ("error3")

if state[0] is 4:
evening()
try:
morning_u()
except:
print ("error4")

最佳答案

我看到两个可能导致您的错误的直接问题。

首先,evening 调用 morning_u 但没有其他函数执行此操作并且它与循环是多余的。

其次,您永远不会在循环中更新 fetch(这是一个糟糕的名字,考虑更像 statetime_of_day 的东西) .循环会一遍又一遍地做同样的事情。

此外,每次函数调用都会断开并重新连接到数据库。这是低效的,并且可能导致并发问题。这些函数最好编写为接受现有的数据库连接。

最后,您有自动提交的 conn.isolation_level = None,但您调用的是 commit。提交是空操作,但它可以让读者误以为您正在使用事务。通常,避免自动提交并使用事务。事务对于并发非常重要。 SQLite defaults to odd implicit transactions这可能不会做你想做的,而且很难弄清楚。我建议使用显式事务。大概 immediate对于最可预测的行为,但不是唯一的。设置 conn.isolation_level = "IMMEDIATE"


在设计方面,您说您想要一个崩溃恢复系统,但您正试图将其用作并发系统。这是两个主要是独家的东西。

崩溃恢复假设在任何时候只有一个进程拥有该状态。它加载,它获得旧状态,然后它愉快地前进,假设它拥有该状态并根据需要更改它。 没有其他人在改变状态。它甚至可以通过表上的独占锁来保证这一点。

并发假定许多进程都在更新状态。由于您正在构建状态机,因此对状态的每次更改都取决于现有状态。对状态的所有更改都必须是原子的:启动事务(即获取锁)、读取状态、更新状态和提交。状态的所有使用也必须是原子的:启动事务(即获取读锁以防止状态更改)、读取状态、使用状态、结束事务。

对于崩溃恢复,您只需要在程序开始时读取状态一次。你只需要在你改变它的时候写它。

对于并发,你必须在程序开始时读取状态,并且任何时候你想使用它。当您使用它时,您必须获得共享锁以确保它不会同时更改。

您拥有崩溃恢复所需的代码,您所缺少的只是确保状态(即 fetch[0])由状态更改函数更新。您没有任何并发​​代码,但您也不需要它。

关于database - 恢复程序的最后状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37633030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com