पर पायथन मल्टीप्रोसेसिंग और नेटवर्किंग मैं एक टीसीपी 'इको सर्वर' को लागू करने की कोशिश कर रहा हूं। सरल सामग्री:विंडोज
- ग्राहक सर्वर को एक संदेश भेजता है।
- सर्वर संदेश
- सर्वर संदेश को अपरकेस में
- सर्वर
- ग्राहक प्रतिक्रिया प्रिंट ग्राहक के लिए संशोधित संदेश भेजता है धर्मान्तरित प्राप्त करता है।
यह अच्छी तरह से काम करता है, इसलिए मैंने सर्वर को समानांतर करने का निर्णय लिया; इसे बनाओ ताकि यह कई ग्राहकों को समय पर संभाल सके। चूंकि अधिकांश पायथन दुभाषियों के पास एक जीआईएल है, इसलिए मल्टीथ्रेडिंग इसे काट नहीं देगा। मुझे मल्टीप्रोसेस का उपयोग करना पड़ा ... और लड़का, यह वह जगह है जहां चीजें डाउनहिल गईं।
मैं विंडोज 10 x64 और पायथन 3.5.2 x64 के साथ WinPython सूट का उपयोग कर रहा हूं।
मेरा विचार सॉकेट बनाना है, इसे intialize (बांधना और सुनना), उप प्रक्रियाएं बनाना और बच्चों को सॉकेट पास करना है। लेकिन मेरे प्यार के लिए ... मैं यह काम नहीं कर सकता, मेरे सबप्रोसेस लगभग तुरंत मर जाते हैं। शुरुआत में मुझे कुछ समस्याएं 'पिकलिंग' सॉकेट थीं ... तो मैंने थोड़ा गुस्सा किया और सोचा कि यह मुद्दा था। इसलिए मैंने एक पाइप के माध्यम से एक मल्टीप्रोसेसिंग कतार के माध्यम से अपनी सॉकेट पास करने का प्रयास किया और मेरा आखिरी प्रयास 'फोर्कपिकलिंग' था और प्रसंस्करण निर्माण के दौरान इसे बाइट ऑब्जेक्ट के रूप में पास कर रहा था। कुछ भी काम नहीं करता है।
क्या कोई यहां कुछ प्रकाश डाल सकता है? मुझे बताओ क्या गलत है? शायद पूरा विचार (साझा करना सॉकेट) खराब है ... और यदि ऐसा है, तो कृपया मुझे बताएं कि मैं अपना प्रारंभिक उद्देश्य कैसे प्राप्त कर सकता हूं: मेरे सर्वर को सक्रिय रूप से एक साथ (विंडोज़ पर) एकाधिक ग्राहकों को संभालने में सक्षम बनाता है (बताएं नहीं मुझे थ्रेडिंग के बारे में, हम सभी जानते हैं कि अजगर का धागा इसे काट नहीं देगा ¬¬)
यह भी ध्यान देने योग्य है कि डीबग फ़ंक्शन द्वारा कोई भी फाइल नहीं बनाई गई है। कोई भी प्रक्रिया इसे चलाने के लिए पर्याप्त समय तक नहीं रहती, मुझे विश्वास है।
अपने सर्वर कोड के विशिष्ट निर्गम (रन के बीच फर्क सिर्फ इतना प्रक्रिया संख्या है):
Server is running...
Degree of parallelism: 4
Socket created.
Socket bount to: ('', 0)
Process 3604 is alive: True
Process 5188 is alive: True
Process 6800 is alive: True
Process 2844 is alive: True
Press ctrl+c to kill all processes.
Process 3604 is alive: False
Process 3604 exit code: 1
Process 5188 is alive: False
Process 5188 exit code: 1
Process 6800 is alive: False
Process 6800 exit code: 1
Process 2844 is alive: False
Process 2844 exit code: 1
The children died...
Why god?
WHYYyyyyy!!?!?!?
सर्वर कोड:
# Imports
import socket
import packet
import sys
import os
from time import sleep
import multiprocessing as mp
import pickle
import io
# Constants
DEGREE_OF_PARALLELISM = 4
DEFAULT_HOST = ""
DEFAULT_PORT = 0
def _parse_cmd_line_args():
arguments = sys.argv
if len(arguments) == 1:
return DEFAULT_HOST, DEFAULT_PORT
else:
raise NotImplemented()
def debug(data):
pid = os.getpid()
with open('C:\\Users\\Trauer\\Desktop\\debug\\'+str(pid)+'.txt', mode='a',
encoding='utf8') as file:
file.write(str(data) + '\n')
def handle_connection(client):
client_data = client.recv(packet.MAX_PACKET_SIZE_BYTES)
debug('received data from client: ' + str(len(client_data)))
response = client_data.upper()
client.send(response)
debug('sent data from client: ' + str(response))
def listen(picklez):
debug('started listen function')
pid = os.getpid()
server_socket = pickle.loads(picklez)
debug('acquired socket')
while True:
debug('Sub process {0} is waiting for connection...'.format(str(pid)))
client, address = server_socket.accept()
debug('Sub process {0} accepted connection {1}'.format(str(pid),
str(client)))
handle_connection(client)
client.close()
debug('Sub process {0} finished handling connection {1}'.
format(str(pid),str(client)))
if __name__ == "__main__":
# Since most python interpreters have a GIL, multithreading won't cut
# it... Oughta bust out some process, yo!
host_port = _parse_cmd_line_args()
print('Server is running...')
print('Degree of parallelism: ' + str(DEGREE_OF_PARALLELISM))
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created.')
server_socket.bind(host_port)
server_socket.listen(DEGREE_OF_PARALLELISM)
print('Socket bount to: ' + str(host_port))
buffer = io.BytesIO()
mp.reduction.ForkingPickler(buffer).dump(server_socket)
picklez = buffer.getvalue()
children = []
for i in range(DEGREE_OF_PARALLELISM):
child_process = mp.Process(target=listen, args=(picklez,))
child_process.daemon = True
child_process.start()
children.append(child_process)
while not child_process.pid:
sleep(.25)
print('Process {0} is alive: {1}'.format(str(child_process.pid),
str(child_process.is_alive())))
print()
kids_are_alive = True
while kids_are_alive:
print('Press ctrl+c to kill all processes.\n')
sleep(1)
exit_codes = []
for child_process in children:
print('Process {0} is alive: {1}'.format(str(child_process.pid),
str(child_process.is_alive())))
print('Process {0} exit code: {1}'.format(str(child_process.pid),
str(child_process.exitcode)))
exit_codes.append(child_process.exitcode)
if all(exit_codes):
# Why do they die so young? :(
print('The children died...')
print('Why god?')
print('WHYYyyyyy!!?!?!?')
kids_are_alive = False
संपादित करें: "सुन" के हस्ताक्षर तय । मेरी प्रक्रियाएं अभी भी तुरंत मर जाती हैं।
संपादित 2: उपयोगकर्ता सेमीिडी ने इंगित किया कि यह कोड लिनक्स पर काम करता है; तो मेरा सवाल है: मैं विंडोज पर यह काम कैसे कर सकता हूं?
मल्टीप्रोसेसिंग स्वचालित रूप से बाल प्रक्रियाओं में सॉकेट पास करने से संभालती है। विंडोज कार्यान्वयन सॉकेट 'शेयर' विधि और 'सेशेयर' फ़ंक्शन का उपयोग करता है। – eryksun
मुख्य प्रक्रिया में 'स्वीकार करें() 'को कॉल करें और एक साझा' multiprocessing.Queue' का उपयोग करके परिणामी '(conn, addr)' tuple को एक कार्यकर्ता को पास करें। – eryksun
कोई बदलाव नहीं, eryksun। मेरी प्रक्रियाएं अभी भी मर जाती हैं। – Trauer