1

我想在一個程序文件中運行UDP服務器端和UDP客戶端的多線程中使用python編寫代碼。我需要確保線程是同步的。多線程在同一個程序中運行UDP客戶端和UDP服務器

問題(據我所知)與我的代碼是,當thread1運行時,它獲得鎖,因爲thread1的run()方法運行serverSide()方法,其中包含永久while循環,thread1不釋放鎖,因此,程序卡住了。

任何人都可以請幫助,同時確保我同步線程的服務器和客戶端運行正常

import threading 
import time 
import sys 
from datetime import datetime 
from socket import * 


class myThread (threading.Thread): 
    def __init__(self, threadID, name, counter): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 
     self.counter = counter 
    def run(self): 
     print "Starting " + self.name 
     # Get lock to synchronize threads 
     threadLock.acquire() 
     serverSide() 
     # Free lock to release next thread 
     threadLock.release() 

class myThread1 (threading.Thread): 
    def __init__(self, threadID, name, counter): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 
     self.counter = counter 
    def run(self): 
     print "Starting " + self.name 
     # Get lock to synchronize threads 
     threadLock.acquire() 
     clientSide() 
     # Free lock to release next thread 
     threadLock.release() 



def serverSide(): 
    serverPort = 44000 
    serverIP = '192.168.0.0' 
    serverSocket = socket(AF_INET, SOCK_DGRAM) 
    serverSocket.bind((serverIP,serverPort)) 
    print ("SERVER HERE!\nThe server is ready to receive") 
    while 1: 
     message, clientAddress = serverSocket.recvfrom(2048) 
     modifiedMessage = message.upper() 
     serverSocket.sendto(modifiedMessage, clientAddress) 


def clientSide(): 
    serverIP = "192.168.0.0" 
    serverPort = 44000 
    clientSocket = socket(AF_INET, SOCK_DGRAM) 
    message = raw_input("CLIENT HERE!\nInput lowercase sentence:") 

    clientSocket.sendto(message.encode(),(serverIP, serverPort)) 
    modifiedMessage, serverAddress = clientSocket.recvfrom(2048) 
    print(modifiedMessage) # print the received message 

    clientSocket.close() # Close the socket 

threadLock = threading.Lock() 
threads = [] 

# Create new threads 
thread1 = myThread(1, "Thread-1", 1) 
thread2 = myThread1(2, "Thread-2", 2) 

# Start new Threads 
thread1.start() 
thread2.start() 

# Add threads to thread list 
threads.append(thread1) 
threads.append(thread2) 

# Wait for all threads to complete 
for t in threads: 
    t.join() 
print "Exiting Main Thread" 
+0

爲什麼你需要threadLock對象?你爲什麼試圖在兩個線程之間進行同步。理想情況下,服務器端和客戶端不會有任何同步。 –

回答

1

你的代碼工作正常,除了同步部分。

所以問題是這樣的,有一個threadLock = threading.Lock()曾經獲得的兩個線程之一,其他線程將無法獲得。

線程一旦獲得它,它就不會釋放它,直到它的工作完成。除非另一個線程正常運行,否則就無法完成工作。另一個線程正在等待第一個線程釋放鎖定。

您已經人爲設法在您的代碼中引發競爭條件,而這並不是必需條件。我只是用線程去除了整個部分並且工作正常。除了我不得不中斷程序來結束它。

import threading 
import time 
import sys 
from datetime import datetime 
from socket import * 


class myThread (threading.Thread): 
    def __init__(self, threadID, name, counter): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 
     self.counter = counter 
    def run(self): 
     print ("Starting " + self.name) 
     # Get lock to synchronize threads 
     # threadLock.acquire() 
     serverSide() 
     # Free lock to release next thread 
     # threadLock.release() 

class myThread1 (threading.Thread): 
    def __init__(self, threadID, name, counter): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 
     self.counter = counter 
    def run(self): 
     print ("Starting " + self.name) 
     # Get lock to synchronize threads 
     # threadLock.acquire() 
     clientSide() 
     # Free lock to release next thread 
     # threadLock.release() 



def serverSide(): 
    serverPort = 44000 
    serverIP = '127.0.0.1' 
    serverSocket = socket(AF_INET, SOCK_DGRAM) 
    serverSocket.bind((serverIP,serverPort)) 
    print ("SERVER HERE!\nThe server is ready to receive") 
    while 1: 
     message, clientAddress = serverSocket.recvfrom(2048) 
     modifiedMessage = message.upper() 
     serverSocket.sendto(modifiedMessage, clientAddress) 


def clientSide(): 
    serverIP = "127.0.0.1" 
    serverPort = 44000 
    clientSocket = socket(AF_INET, SOCK_DGRAM) 
    message = input("CLIENT HERE!\nInput lowercase sentence:") 

    clientSocket.sendto(message.encode(),(serverIP, serverPort)) 
    modifiedMessage, serverAddress = clientSocket.recvfrom(2048) 
    print("received", modifiedMessage) # print the received message 

    clientSocket.close() # Close the socket 

# threadLock = threading.Lock() 
threads = [] 

# Create new threads 
thread1 = myThread(1, "Thread-1", 1) 
thread2 = myThread1(2, "Thread-2", 2) 

# Start new Threads 
thread1.start() 
thread2.start() 

# Add threads to thread list 
threads.append(thread1) 
threads.append(thread2) 

# Wait for all threads to complete 
for t in threads: 
    t.join() 
print ("Exiting Main Thread") 

輸出:

Starting Thread-1 
Starting Thread-2 
SERVER HERE! 
The server is ready to receive 
CLIENT HERE! 
Input lowercase sentence:viki 
received b'VIKI' 

注:

我試圖用Python語言編寫代碼,使用多線程,運行在一個程序中UDP服務器端和UDP客戶端文件。我需要確保線程是同步的。

客戶端服務器架構在大多數情況下不應該同步。 Google服務器和我的瀏覽器不同步。它們不應該是相同的適用於您的代碼。原因是服務器應該獨立於客戶端運行或不運行。

客戶端應該獨立於服務器是否運行起來運行。如果服務器關閉,客戶端請求將失敗。但它仍然應該運行。

+1

我完全同意你的看法。服務器和客戶端不應該同步,服務器應該獨立運行。我想同步的原因是因爲我一直在努力實現鏈路狀態路由協議,其中六個不同的路由器將運行他們自己的服務器和客戶端。因此,每個路由器都有自己的服務器和客戶端,它們應該在單個程序文件中運行。由於數據處理是在客戶端和服務器端完成的,我想同步它們。但從概念上說,同步並不是正確的解決方案。 謝謝你! –

+0

首先,祝你新年快樂@Areeba :)第二:我認爲你有一個問題陳述,你認爲客戶端和服務器之間的同步將解決它。也許會。但是,如果你能解釋你到底想要解決什麼問題,也許我們可以想出一個不同的結構來解決這個問題。 –

+0

祝你新年快樂! 問題陳述是退出很長時間,所以我不認爲我可以在這裏發帖 –