Поскольку вы используете ProcessPoolExecutor
, вам нужно использовать объект, безопасный для процесса, вместо обычного целого. Если вам нужно только поддерживать Linux (и поэтому может рассчитывать на наличие fork()
), вы можете просто использовать обычный, глобальный multiprocessing.Value
, чтобы сделать это.
import asyncio
import multiprocessing
from concurrent.futures import ProcessPoolExecutor
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from datetime import datetime
import time
def day_limits():
variable.value = 90
print ('Day Variable: ',variable.value)
def night_limits():
variable.value = 65
print ('Night Variable: ',variable.value)
def thread_2():
while True:
c_hour = int(datetime.now().strftime("%H"))
c_min = int(datetime.now().strftime("%M"))
c_sec = int(datetime.now().strftime("%S"))
print ('%02d:%02d:%02d - Variable: %d ' % (c_hour,c_min,c_sec,variable.value))
time.sleep(2)
if __name__ == "__main__":
variable = multiprocessing.Value('i', 60)
scheduler = AsyncIOScheduler()
scheduler.add_job(day_limits, 'cron', hour=7,misfire_grace_time=3600,timezone='GB')
scheduler.add_job(night_limits, 'cron', hour=19, minute=32,misfire_grace_time=3600,timezone='GB')
scheduler.start()
scheduler.print_jobs()
executor = ProcessPoolExecutor(1)
loop = asyncio.get_event_loop()
baa = asyncio.async(loop.run_in_executor(executor, thread_2))
try:
loop.run_forever()
except (KeyboardInterrupt, Exception):
loop.stop()
scheduler.shutdown()
Если вам необходимо поддерживать как Windows, и Linux, вам нужно использовать multiprocessing.Manager
для создания Value
объекта, и явно передать этот объект в функцию вы работаете в Executor
:
import asyncio
import multiprocessing
from concurrent.futures import ProcessPoolExecutor
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from datetime import datetime
import time
def day_limits():
variable.value = 90
print ('Day Variable: ',variable.value)
def night_limits():
variable.value = 65
print ('Night Variable: ',variable.value)
def thread_2(variable):
while True:
c_hour = int(datetime.now().strftime("%H"))
c_min = int(datetime.now().strftime("%M"))
c_sec = int(datetime.now().strftime("%S"))
print ('%02d:%02d:%02d - Variable: %d ' % (c_hour,c_min,c_sec,variable.value))
time.sleep(2)
if __name__ == "__main__":
m = multiprocessing.Manager()
variable = m.Value('i', 60)
scheduler = AsyncIOScheduler()
scheduler.add_job(day_limits, 'cron', hour=7,misfire_grace_time=3600,timezone='GB')
scheduler.add_job(night_limits, 'cron', hour=19, minute=32,misfire_grace_time=3600,timezone='GB')
scheduler.start()
scheduler.print_jobs()
executor = ProcessPoolExecutor(1)
loop = asyncio.get_event_loop()
baa = asyncio.async(loop.run_in_executor(executor, thread_2, variable)) # Need to pass variable explicitly
try:
loop.run_forever()
except (KeyboardInterrupt, Exception):
loop.stop()
scheduler.shutdown()
Поскольку Windows не имеет поддержки fork
, вам необходимо явно передать Value
функции, которую вы используете в Executor
. Если вы этого не сделаете, дочерний процесс скажет, что переменная не существует. Однако, поскольку вы явно передаете Value
методу run_in_executor
, вы не можете использовать обычный multiprocessing.Value
- вы получите сообщение RuntimeError
, в котором говорится, что «Синхронизированные объекты должны делиться только между процессами через наследование».
Использование multiprocessing.Manager
работ вокруг этого; multiprocessing.Manager
запускает процесс, который может создавать и управлять объектами, совместно использующими процессы. Вызов m.Value()
возвращает Proxy
к общему Value
и что Proxy
может быть отправлен в run_in_executor
без привлечения исключения.
Это ваш полный фрагмент кода? Не понимаете, где вызываются функции? – shongololo
В нижней части главной области. Два вызываются через APscheduler и работают корректно. Конечной вещью является нить asyncio (линия baa). – LikesAChallenge