4

I have a basic question about multi-threading in Python: I have a list and I need modify this in a thread. I understand that an list is a mutable type: How do I pass a variable by reference?

But, when I using thread the list is not behaving like a mutable type:

from multiprocessing import Process, Lock

def f(l, i, n):
    l.acquire()
    i.append(n)
    l.release()
    print "in:", i

if __name__ == '__main__':
    lock = Lock()

    i = []
    for num in range(10):
        p = Process(target=f, args=(lock, i, num))
        p.start()
        p.join()

    print "out:", i

output

in: [0]
in: [1]
in: [2]
in: [3]
in: [4]
in: [5]
in: [6]
in: [7]
in: [8]
in: [9]
out: []

Can someone please help me with this issue?

Community
  • 1
  • 1
Alan Valejo
  • 1,305
  • 3
  • 24
  • 44

2 Answers2

5

The code is not using threads, but processes which does not share memory.

Use threads:

from threading import Thread, Lock  # <----

def f(l, i, n):
    l.acquire()
    i.append(n)
    l.release()
    print "in:", i

if __name__ == '__main__':
    lock = Lock()

    i = []
    for num in range(10):
        p = Thread(target=f, args=(lock, i, num))  # <----
        p.start()
        p.join()

    print "out:", i
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • I tested this, but it looks like Python threads all executing on a single core! Can you tell me why? – Alan Valejo Dec 10 '14 at 15:19
  • Is possible to use Python Multiprocess and the list behave like a mutable type? – Alan Valejo Dec 10 '14 at 15:30
  • @AlanValejo, Reading [**Sharing state between processes - Python multiprocessing module documentation**](https://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes) will be helpful. – falsetru Dec 10 '14 at 15:32
1

You need to join on a seperate loop. By having the join in the same loop, it forces you to wait for the thread to complete before kicking off the next thread. See code below...

from threading import Thread, Lock  # <----

def f(l, i, n):
    l.acquire()
    i.append(n)
    l.release()
    print "in:", i

if __name__ == '__main__':
    lock = Lock()

    i = []
    for num in range(10):
        p = Thread(target=f, args=(lock, i, num))  # <----
        p.start()
        
    for num in range(10):
        p.join()   

    print "out:", i
Ron Klar
  • 11
  • 1