2017-01-26 69 views
0

我有這個腳本創建一個UDP服務器,它接收一個流並將其放入一個數組中。每分鐘後,我都會攝入數據,清理並將其發送到另一臺服務器。這兩個操作都在共享相同變量的頭上運行。避免多線程UDP服務器中的數據丟失

import socket, time, threading, copy 

UDP_IP = "255.255.255.255" 
UDP_PORT = 4032 

store = [] 

lock = threading.Lock() 

def receive_data(): 
    global queue 
    global lock 

    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    s.bind((UDP_IP, UDP_PORT)) 

    while True: 
     data = s.recv(9999) 
     # store data temporarily 
     lock.acquire() 
     store.append(data) 
     lock.release() 

def send_data(): 
    global store 
    global lock 

    lock.acquire() 
    data = copy.deepcopy(store) 
    store = [] 
    lock.release() 

    # Clean up, send and put a timer 
    threading.Timer(60, send_data).start() 

t1 = threading.Thread(target=receive_data, name='Server') 
t1.start() 

t2 = threading.Thread(target=send_data, name='Sender') 
t2.start() 

我的問題:這是一個足夠好的腳本避免數據丟失?我擔心,如果鎖定變量可能會使UDP服務器處於保留狀態以訪問它並以某種方式跳過在此期間發送的數據。

+0

您的代碼不顯示UDP線程處理鎖。它似乎沒有等待。 – quamrana

+3

常見模式是使用線程之間共享的隊列。隊列是線程安全的,所以你所有的發送函數都需要定期檢查是否有新的數據併發送它。這意味着在任何函數中都不需要鎖定機制。 –

+1

也許你應該使用線程安全的'Queue'。 https://docs.python.org/2/library/queue.html或https://docs.python.org/3.6/library/queue.html –

回答

1

假設你的代碼是這樣的:

import socket, time, threading, copy 

UDP_IP = "255.255.255.255" 
UDP_PORT = 4032 

store = [] 

lock = threading.Lock() 

def receive_data(): 
    global store 
    global lock 
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    s.bind((UDP_IP, UDP_PORT)) 

    while True: 
     data = s.recv(9999) 
     # store data temporarily 
     lock.acquire() # Note the lock around access to global store 
     store.append(data) 
     lock.release() 

def send_data(): 
    global store 
    global lock 

    lock.acquire() 
    data = store[:] # cheap copy of the contents while locked 
    store = [] 
    lock.release() 

    # Expensive processing of data to send it to another server 
    process(data) 

    # Clean up, send and put a timer 
    threading.Timer(60, send_data).start() 

t1 = threading.Thread(target=receive_data, name='Server') 
t1.start() 

t2 = threading.Thread(target=send_data, name='Sender') 
t2.start() 

則沒有敲竹槓只要讀取數據關注。無論如何,套接字將爲你緩衝數據。

+0

謝謝你的回答... – Daniyal