Я пытаюсь создать архитектуру, которая будет иметь основной родительский процесс и может создавать новые дочерние процессы. Главный родительский процесс всегда будет на l oop, чтобы проверить, доступен ли какой-либо дочерний процесс.
Я использовал ThreadedConnectionPool модуля psycopg2.pool для создания общего подключения к базе данных для всех созданных дочерних процессов. , Это означает, что программа будет один раз подключаться к базе данных и выполнять все запросы SQL для каждого из дочерних процессов. Таким образом, нет необходимости каждый раз подключаться к базе данных для выполнения SQL запросов.
Код выглядит следующим образом:
from multiprocessing import Process, Lock
import time, os, psycopg2
from psycopg2 import pool
def child(dbConnection, lock, num, pid, sleepTime, query):
lock.acquire()
start = time.time()
print("Child Process {} - Process ID: {}".format(num + 1, str(os.getpid())))
db_cursor = dbConnection.cursor()
db_cursor.execute(query)
records = db_cursor.fetchmany(2)
print("Displaying rows from User Master Table")
for row in records:
print(row)
print("Executed Query:", query)
print("Child Process {} - Process ID {} Completed.".format(num + 1, str(os.getpid())))
end = time.time()
print("Time taken:", str(end - start), "seconds")
lock.release()
time.sleep(sleepTime)
if __name__ == "__main__":
try:
connectionPool = psycopg2.pool.ThreadedConnectionPool(5, 21, user = "dwhpkg", password = "dwhpkg", host = "127.0.0.1", port = "5432", database = "dwhdb")
while True:
processes = []
print("Main Process ID: {}".format(str(os.getpid())))
lock = Lock()
# 21 Times Process Execution
for count in range(21):
if connectionPool :
print("Connection Pool Successfully Created")
# Getting DB Connection From Connection Pool
dbConnection = connectionPool.getconn()
if dbConnection:
sql_execute_process = Process(target = child, args = (dbConnection, lock, count, os.getpid(), 4, 'SELECT * FROM public."USER_MASTER"',))
sql_execute_process.start()
processes.append(sql_execute_process)
print("Parent Process:", os.getpid())
print(processes)
time.sleep(5)
for process in processes:
process.join()
except (Exception, psycopg2.DatabaseError) as error:
print("Error Connecting To PostgreSQL", error)
finally:
# Closing DB Connection
if connectionPool:
connectionPool.closeall
print("Connection Pool is closed")
При попытке запустить приведенный выше код выдает следующую ошибку:
Main Process ID: 46700
Connection Pool Successfully Created
Error Connecting To PostgreSQL can't pickle psycopg2.extensions.connection objects
Connection Pool is closed
(task_env) C:\Users\sicuser\Desktop\ジート\03_作業案件\タスク機能プロトタイプ作成\開発>Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\sicuser\AppData\Local\Programs\Python\Python37\lib\multiprocessing\spawn.py", line 99, in spawn_main
new_handle = reduction.steal_handle(parent_pid, pipe_handle)
File "C:\Users\sicuser\AppData\Local\Programs\Python\Python37\lib\multiprocessing\reduction.py", line 82, in steal_handle
_winapi.PROCESS_DUP_HANDLE, False, source_pid)
OSError: [WinError 87] The parameters are incorrect.
Для устранения неполадок также использовал режим отладки и попытался выяснить местоположение ошибки. Используя отладку, я обнаружил, что ошибка происходит из-за следующей строки:
sql_execute_process.start()
Message Сообщение об ошибке】
Main Process ID: 47708
Connection Pool Successfully Created
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\sicuser\AppData\Local\Programs\Python\Python37\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File "C:\Users\sicuser\AppData\Local\Programs\Python\Python37\lib\multiprocessing\spawn.py", line 115, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input
Error Connecting To PostgreSQL can't pickle psycopg2.extensions.connection objects
Среда ОС Windows и Python версия: Python 3.7.4
Ждем поддержки от экспертов.