Tôi hy vọng mã sau sẽ in [{0: 100}]
, vì nó thực hiện cộng vào updateList
trong một trăm lần, nó in [{0: 0}]
Vấn đề là gì và làm thế nào để khắc phục nó?
from multiprocessing import Process, Lock, Value,Manager
class myWorker:
def __init__[self, lock, driver, i]:
self.idx=i
self.driver=driver
self.lock=lock
def run[self]:
self.driver.updateList[self.lock,self.idx]
class driver[object]:
def __init__[self]:
manager=Manager[]
self.lock=Lock[]
self.lst=manager.list[]
self.dict1=manager.dict[{0:0}]
self.lst.append[self.dict1]
def workerrun[self,lock, i]:
worker1=myWorker[lock,self,i]
worker1.run[]
def run[self]:
D=[Process[target=self.workerrun,args=[self.lock,i]] for i in range[10]]
for d in D:
d.start[]
for d in D:
d.join[]
def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
self.lst[0][0]+=1
print ["update from", i]
if __name__=='__main__':
dr=driver[]
dr.run[]
print[dr.lst]
Hỏi ngày 25 tháng 10 năm 2014 lúc 12:19Oct 25, 2014 at 12:19
william007william007william007
16.5K21 Huy hiệu vàng104 Huy hiệu bạc174 Huy hiệu đồng21 gold badges104 silver badges174 bronze badges
1
def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
d = self.lst[0]
d[0] += 1
self.lst[0]=d
print ["update from", i,self.lst[0]]
từ các tài liệu
Lưu ý sửa đổi các giá trị hoặc mục có thể thay đổi trong các proxy Dict và Liệt kê sẽ không được truyền qua người quản lý, bởi vì proxy không có cách nào biết khi nào giá trị hoặc mục của nó được sửa đổi. Để sửa đổi một mục như vậy, bạn có thể gán lại đối tượng đã sửa đổi cho proxy container:
Nhìn thấy khi bạn đã có ____10, bạn có thể cập nhật trực tiếp:
def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
self.dict1[0]+=1
print ["update from", i,self.lst[0]]
Đã trả lời ngày 25 tháng 10 năm 2014 lúc 12:46Oct 25, 2014 at 12:46
0
def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
d = self.lst[0]
d[0] += 1
self.lst[0]=d
print ["update from", i,self.lst[0]]
1 trả về một def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
d = self.lst[0]
d[0] += 1
self.lst[0]=d
print ["update from", i,self.lst[0]]
2 Nếu bạn thấy khi bạn tạo danh sách và từ điển, bạn thực sự đã có proxy của họ. Điều đó có nghĩa là, những gì bạn đã thêm vào danh sách chứ không phải def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
d = self.lst[0]
d[0] += 1
self.lst[0]=d
print ["update from", i,self.lst[0]]
3 mà bạn đã tạo bên trong trình quản lý mà là một proxy [bản sao].self.dict1=manager.dict[{0:0}]
#this:
self.lst.append[self.dict1]
#is the same as doing this:
self.lst.append[{0:0}]
Vì vậy, trong phương thức Updatelist:
def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
self.lst[0][0]+=1
# is the same as doing:
# example: self.lst == [{0:x}]
proxy = self.lst
# you get a copy of actual list
# proxy == [{0:x}]
dict = proxy[0]
dict[0]+=1
# proxy == [{0:x+1}]
# BUT
# self.lst == [{0:x}]
Điều đó có nghĩa là bạn đang tạo các bản sao, thay đổi chúng, và sau đó không sử dụng chúng. Bạn cần thay đổi để gán danh sách với giá trị mới để nó thay đổi cho tất cả các quy trình:
def updateList[self,l,i]:
with self.lock: # acquire lock
dict0 = self.lst[0]
for j in range[10]:
dict0[0]+=1
self.lst[0] = dict0
Đã trả lời ngày 25 tháng 10 năm 2014 lúc 13:21Oct 25, 2014 at 13:21
Bạn có thể chỉnh lưu nó bằng cách cập nhật từ điển trực tiếp.
def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
self.dict1[0] += 1
print ["update from", i]
Mặc dù, tại sao vòng lặp để thêm 10? Loại bỏ vòng lặp và chỉ làm
def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
d = self.lst[0]
d[0] += 1
self.lst[0]=d
print ["update from", i,self.lst[0]]
4.Đã trả lời ngày 25 tháng 10 năm 2014 lúc 12:46Oct 25, 2014 at 12:46
def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
d = self.lst[0]
d[0] += 1
self.lst[0]=d
print ["update from", i,self.lst[0]]
1 trả về một def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
d = self.lst[0]
d[0] += 1
self.lst[0]=d
print ["update from", i,self.lst[0]]
2 Nếu bạn thấy khi bạn tạo danh sách và từ điển, bạn thực sự đã có proxy của họ. Điều đó có nghĩa là, những gì bạn đã thêm vào danh sách chứ không phải def updateList[self,l,i]:
with self.lock: # acquire lock
for j in range[10]:
d = self.lst[0]
d[0] += 1
self.lst[0]=d
print ["update from", i,self.lst[0]]
3 mà bạn đã tạo bên trong trình quản lý mà là một proxy [bản sao].mhawkeVì vậy, trong phương thức Updatelist:9 gold badges113 silver badges135 bronze badges