2014-04-09 69 views
0

如果我一步一步地運行腳本完美工作,但是當我使用線程時會丟失50-60%。我使用Python +機械化模塊Python多線程缺失作業

#setting up the browser 
mySite = 'http://example.com/managament.php?' 
postData = {'UserID' : '', 'Action':'Delete'} 
job_tab1_user1 = [1,2,3] 
job_tab2_user1 = [4,5,6] 
job_tab1_user2 = [7,8,9] 
job_tab2_user2 = [10,12,13] 
.... till user1000 
#i want to point out that the lists are 100% different 
def user1_jobs: 
    for i in job_tab1_user1: 
     browser.open("http://example.com/jobs.php?actions="+i) 
     browser.open(mySite, Post_data) 
    for i in job_tab2_user1: 
     browser.open("http://example.com/jobs.php?actions="+i) 
     browser.open(mySite, Post_data) 
def user2_jobs: 
    for i in job_tab1_user2: 
     browser.open("http://example.com/jobs.php?actions="+i) 
     browser.open(mySite, Post_data) 
    for i in job_tab2_user2: 
     browser.open("http://example.com/jobs.php?actions="+i) 
     browser.open(mySite, Post_data) 
... and so on till user 1000 

我呼籲他們到底是這樣的:

t_user1 = threading.Thread(target=user1_jobs, args=[]) 
t_user1.start() 
t_user2 = threading.Thread(target=user2_jobs, args=[]) 
t_user2.start() 

我有一個像發送每秒200請求和所有的人都處理類似的腳本。我也嘗試過使用time.sleep(2),但又一次缺少了很多。 除了我的腳本有什麼問題之外,另一個問題是如果它壓縮此代碼的方式,因爲我使用了1000個用戶並且腳本達到了數千行。先謝謝你。

+2

爲什麼不使用'Queue.Queue'類來存儲所有的工作?然後您可以使用線程池來處理隊列中的作業。 –

+0

當你說「錯過」時,它錯過了什麼? – Torxed

+0

@Toxxed將發佈的數據發送到服務器。示例:對於user1,tab1中的作業,user2中的作業,tab2中的作業。所以它是隨機完成的。 – MikeT

回答

1
from threading import * 

submits = [[1,2,3], [3,4,5], [6,7,8]]  

class worker(Thread): 
    def __init__(self, site, postdata, data): 
     Thread.__init__(self) 
     self.data = data 
     self.site = site 
     self.postdata = postdata 
     self.start() 
    def run(self): 
     for i in self.data: 
      browser.open("http://example.com/jobs.php?actions="+str(i)) 
      browser.open(self.site, self.postdata) 
for obj in submits: 
    worker('http://example.com/managament.php?', {'UserID' : '', 'Action':'Delete'}, submits) 

由於OP提出要求,下面是代碼的精簡/壓縮版本。

或:

for index in range(0,1000): 
    worker('http://example.com/managament.php?', {'UserID' : '', 'Action':'Delete'}, [i for i in range(1,4)]) 

如果要實際發送的數據是3個整數(1,2,3),在一個完美的秩序傾斜的序列。

+0

'submits'是一個列表,因此不是線程安全的。 –

+0

@GamesBrainiac在這個特定的情況下,是的,但如果更新或更改大小時迭代它可能會導致問題?如果不是這樣,它仍然是一個壞主意教導一些不普遍的功能,可以(我f使用其他變量類型)會導致麻煩。 Eveno你應該使用信號對象或隊列:) – Torxed

+0

讓我們在聊天中討論這個。 –

1

這是一個完整的腳本,您可以通過更改初始變量輕鬆進行修改。 它動態創建一個列表並使用一個生成器爲每個線程創建函數。 目前它創建1000個用戶,每個用戶有2個選項卡和3個作業。

# define your variables here 
NUM_USERS = 1000 
NUM_JOBS_PER_USER = 3 
NUM_TABS_PER_USER = 2 
URL_PART = "http://example.com/jobs.php?actions=" 

# populate our list of jobs 
# the structure is like this: jobs[user][tab][job] 

jobs = [[[0 for y in range(NUM_JOBS_PER_USER)] \ 
      for x in range(NUM_TABS_PER_USER)] \ 
      for x in range(NUM_USERS)] 
p = 1 
for i in range(NUM_USERS): 
    for j in range(NUM_TABS_PER_USER): 
     for k in range(NUM_JOBS_PER_USER): 
      jobs[i][j][k] = p 
      p += 1 


# create a generator that builds our thread functions 
def generateFunctions(jobs): 
    for user in jobs: 
     for tab in user: 
      for job in tab: 
       def f(): 
        browser.open(URL_PART + str(job)) 
        browser.open(mySite, Post_data) 
       yield f 

# create and start threads, add them to a list 
# if we need to preserve handlers for later use 
threads = [] 
for f in generateFunctions(jobs): 
    thr = threading.Thread(target = f, args=[]) 
    thr.start() 
    threads.append(thr) 
+0

我必須比如說,你已經將一大套代碼轉換成了更大一些的代碼。我確定它可以工作,但是你的'for'循環可以被壓縮很多。 – Torxed

+0

這是如何比幾千行更大的?它可以更濃縮,當然。 – bosnjak