python新手学习进程与线程,Queue使用问题

不到82kg不改名
  • 5
新手上路,请多包涵

各位大佬,我刚刚开始学骆昊老师的Python100Day,遇到一些问题想问问大家。
程序要求是:启动两个进程,一个输出Ping,一个输出Pong,两个进程输出的Ping和Pong加起来共10个。
我尝试着使用骆昊老师提到的Queue类来解决问题,代码如下:

from multiprocessing import Process, Queue
from time import sleep
from os import getpid

counter = 0

def sub_task(My_string, q):
    c = q.get()
    while c < 10:
        c += 1
        print('字符串为:%s;counter的值为:%d;使用的进程号为:%d' % (My_string, c, getpid()))
        q.put(c)

def main():
    q = Queue()
    q.put(counter)
    p1 = Process(target=sub_task, args=('Ping', q))
    p1.start()
    p2 = Process(target=sub_task, args=('Pong', q))
    p2.start()
    p1.join()
    p2.join()

    return

if __name__ == "__main__":
    main()

输出的结果如下:

字符串为:Pong;counter的值为:1;使用的进程号为:15044
字符串为:Pong;counter的值为:2;使用的进程号为:15044
字符串为:Pong;counter的值为:3;使用的进程号为:15044
字符串为:Pong;counter的值为:4;使用的进程号为:15044
字符串为:Pong;counter的值为:5;使用的进程号为:15044
字符串为:Pong;counter的值为:6;使用的进程号为:15044
字符串为:Pong;counter的值为:7;使用的进程号为:15044
字符串为:Pong;counter的值为:8;使用的进程号为:15044
字符串为:Pong;counter的值为:9;使用的进程号为:15044
字符串为:Pong;counter的值为:10;使用的进程号为:15044
字符串为:Ping;counter的值为:2;使用的进程号为:16684
字符串为:Ping;counter的值为:3;使用的进程号为:16684
字符串为:Ping;counter的值为:4;使用的进程号为:16684
字符串为:Ping;counter的值为:5;使用的进程号为:16684
字符串为:Ping;counter的值为:6;使用的进程号为:16684
字符串为:Ping;counter的值为:7;使用的进程号为:16684
字符串为:Ping;counter的值为:8;使用的进程号为:16684
字符串为:Ping;counter的值为:9;使用的进程号为:16684
字符串为:Ping;counter的值为:10;使用的进程号为:16684

我想问下,为什么利用Queue传递counter变量后,仍然会输出超过十个Ping和Pong,出现这个错误的原因是什么?请求各位大佬不吝赐教。谢谢。

回复
阅读 380
1 个回答
✓ 已被采纳

因为你的c自从c = q.get()后其实就不再从q里获取值了,p1从q中读取0,往q中插入1到10,而p2从q中读取1,往q中插入2到10。
如果你想要测并发的效果,可以试试

from multiprocessing import Process, Queue
from time import sleep
from os import getpid

counter = 0

def sub_task(My_string, q):
    while (c := q.get())  < 10:
        c += 1
        print('字符串为:%s;counter的值为:%d;使用的进程号为:%d' % (My_string, c, getpid()))
        q.put(c)

def main():
    q = Queue()
    q.put(counter)
    p1 = Process(target=sub_task, args=('Ping', q))
    p1.start()
    p2 = Process(target=sub_task, args=('Pong', q))
    p2.start()
    p1.join()
    p2.join()

    return

if __name__ == "__main__":
    main()
宣传栏