Socket多进程环境下无法序列化_thread.lock问题求助
_thread.lock in Python Multiprocessing Hey there, let's break down what's going on here and fix that error you're hitting.
The Root Cause
You're seeing Can't pickle <class '_thread.lock'> because when using multiprocessing.Process on Windows (with Python 3.5, which uses the spawn start method by default), every argument passed to the child process needs to be serialized with pickle. Your IQ_Option instance has an internal _thread.lock object, which pickle can't serialize—hence the error. The WinError 87 is just a secondary issue from the failed child process spawn.
Solutions (Ordered by Recommendation)
1. Initialize IQ_Option in the Child Process (Best Approach)
Instead of passing the pre-initialized IQ_Option instance from the main process to the child, let each child process create its own instance. This avoids serialization entirely and aligns with how multiprocessing is designed to work (isolated processes).
Here's how to adjust your server code:
import multiprocessing import socket from iqoptionapi.stable_api import IQ_Option import time def handle(client_socket, address): # Create IQ_Option instance INSIDE the child process I_want_money = IQ_Option("email","password") I_want_money.suspend = 0.1 print(f"Connection from {address}") # Bonus: Keep the connection open to handle multiple client messages try: while True: data = client_socket.recv(1024) if not data: # Client closed the connection break client_socket.sendall("Happy".encode()) finally: client_socket.close() class Server(object): def __init__(self, hostname, port): self.hostname = hostname self.port = port print("I am ON.........") def start(self): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.bind((self.hostname, self.port)) self.socket.listen(1) while True: conn, address = self.socket.accept() # No need to pass I_want_money anymore process = multiprocessing.Process(target=handle, args=(conn, address,)) process.daemon = True process.start() if __name__ == "__main__": server = Server("0.0.0.0", 9000) try: server.start() except Exception as e: print(f"{e}\n I had experienced at initialization") finally: for process in multiprocessing.active_children(): process.terminate() process.join()
2. Use multiprocessing.Manager for Shared Objects (If You Need Shared State)
If you absolutely need to share the IQ_Option state between the main process and children, you can use multiprocessing.Manager to create a proxy object that can be safely passed between processes. Note that this adds overhead and may not work with all methods of IQ_Option, so test carefully:
# Modify the Server __init__ method def __init__(self, hostname, port): self.hostname = hostname self.port = port from multiprocessing import Manager manager = Manager() # Create a shared proxy of IQ_Option self.I_want_money = manager.IQ_Option("email","password") self.I_want_money.suspend = 0.1 print("I am ON.........")
3. Switch to fork Start Method (Linux/macOS Only)
Windows doesn't support the fork start method, but if you were on Linux or macOS, you could use it to avoid serialization entirely (fork copies the parent process's memory). Since you're on Windows, this isn't an option for you, but it's worth noting for future reference:
if __name__ == "__main__": multiprocessing.set_start_method('fork') # Rest of your code...
Quick Fix for Your Client Code
Your client sends 100 messages, but the original server closes the socket after the first response. The adjusted handle function above keeps the connection open to handle all messages, which will fix any "broken pipe" errors you might hit on the client side.
内容的提问来源于stack exchange,提问作者Jaffer Wilson

