В следующем коде я объявляю GlobalCount, который должен стать глобальной переменной. Затем я запускаю методprocess() с многопроцессорной обработкой, которая увеличивает GlobalCount каждую секунду. Если я установлю там точку останова, значение увеличится нормально. Затем параллельно я запрашиваю GETSTATUS, который должен вернуть значение GlobalCount. Однако это всегда 0! Что я делаю неправильно? Спасибо.
Обновленный код:
import multiprocessing
import socket
import time
from multiprocessing import Value
#globals
GlobalCount = Value('i', 0) # 'i' stands for integer
def main():
server_ip = "127.0.0.1"
server_port = 2222
# Create a UDP socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = (server_ip, server_port)
server_socket.bind(server_address)
response = ""
print("UDP server is listening on {}:{}".format(*server_address))
while True:
# Receive data from the client
data, client_address = server_socket.recvfrom(256)
if data:
data_str = data.decode('utf-8')
arrayParams = data_str.split(';')
if arrayParams[0] == "PROCESS":
server_socket.sendto(response.encode(), client_address)
# Start the process in parallel
training_process = multiprocessing.Process(target=process)
training_process.start()
elif arrayParams[0] == "GETSTATUS":
current_value = GlobalCount.value
response = str(current_value) #here GlobalCount is always 0
server_socket.sendto(response.encode(), client_address)
else:
print("")
def process():
for i in range(100):
with GlobalCount.get_lock(): # Ensure thread-safety when updating the value
GlobalCount.value += 1
time.sleep(1)
#Execute at start
if __name__ == '__main__':
main()
В Python многопроцессорная обработка создает не поток, а процесс с собственным пространством памяти.
Вы можете попробовать что-то подобное, используя multiprocessing.Value :
from multiprocessing import Value
GlobalCount = Value('i', 0) # 'i' stands for integer
# In your process function:
def process():
for i in range(100):
with GlobalCount.get_lock(): # Ensure thread-safety when updating the value
GlobalCount.value += 1
time.sleep(1)
# When reading the value:
current_value = GlobalCount.value
Редактировать после комментария:
import multiprocessing
import socket
import time
def main():
# Use multiprocessing.Value to create a shared variable
GlobalCount = multiprocessing.Value('i', 0)
server_ip = "127.0.0.1"
server_port = 2222
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = (server_ip, server_port)
server_socket.bind(server_address)
print("UDP server is listening on {}:{}".format(*server_address))
while True:
data, client_address = server_socket.recvfrom(256)
if data:
data_str = data.decode('utf-8')
arrayParams = data_str.split(';')
if arrayParams[0] == "PROCESS":
response = "Started processing"
server_socket.sendto(response.encode(), client_address)
training_process = multiprocessing.Process(target=process, args=(GlobalCount,))
training_process.start()
elif arrayParams[0] == "GETSTATUS":
response = str(GlobalCount.value)
server_socket.sendto(response.encode(), client_address)
def process(GlobalCount):
for i in range(100):
# Modify the shared variable using GlobalCount.value
GlobalCount.value += 1
time.sleep(1)
if __name__ == '__main__':
main()
Должен ли я продолжать устанавливать в метод «глобальный GlobalCount»?
Нет, вместо глобального GlobalCount -> multiprocessing.Value
Та же проблема. GlobalCount всегда равен 0 при запросе значения. Я обновил код на основе вашего предложения.
Синхронизированный объект не является итерируемым... multiprocessing.Process(target=process, args=(GlobalCount))
тот же подход, что и в чатгпт... который я тоже пробовал сначала. Не работает
GPT предлагает подход с многопроцессорной обработкой. Для меня очередь. Я думаю, это не подходит. Не могли бы вы предоставить больше результатов вашего адаптированного кода?
Спасибо, многопоточность вместо многопроцессорности решила проблему.
Приятно знать, спасибо.
Совместно использовать синхронизированные объекты можно только посредством наследования. Вот пример:
from multiprocessing import Value, Pool
N = 100
def ipp(v):
global gCount
gCount = v
def process(_):
with gCount.get_lock():
gCount.value += 1
def main():
gCount = Value('Q', 0) # unsigned long long
with Pool(initializer=ipp, initargs=(gCount,)) as pool:
pool.map(process, range(100))
print(gCount.value == N)
if __name__ == '__main__':
main()
Выход:
True
Я перешел на многопоточность, как вы предложили... И при том же подходе глобального var все работает как положено! Спасибо
Многопоточность, вероятно, лучше подойдет для этого.