python3的信号量的东西!!!!!

多线程和多进程

从目前我用的角度来看,我用它来做的作用就是一个下载爬下来的文件呢,所以我们的io操作比较密集,多线程在本质上说在一个时间片内仅仅只有一个线程在执行,所以并不是真真意义上的多线程并发执行,而多进程是发挥我们cpu多核的优势,在同一个时间片内是有多个进程在同时的执行。所以对于io比较密集的,我们还是用多进程比多线程更加好一点。

回到正题啊。

import time
import threading

s1 = threading.Semaphore(5)  # 添加一个计数器


def foo():
    s1.acquire()  # 计数器获得锁
    time.sleep(2)  # 程序休眠2秒
    print("ok", time.ctime())
    s1.release()  # 计数器释放锁

if __name__ == '__main__':
    
      for i in range(20):
          t1 = threading.Thread(target=foo, args=())  # 创建线程
          t1.start()  # 启动线

先说一下,Semaphore,这个东西得作用就像线程池一样,在我们初始化得时候,输入一个int类型得参数得时候,就代表我们创建得信号量的大小为参数的大小,当信号量使用s1.acquire()我们的信号量就进行 -1 。当信号量使用 s1.release()我们的信号量就进行 +1 操作,当我们的信号量为0的时候,就会发生阻塞,当信号量大于等于1的时候,再继续执行操作。所以就可以当作是我们的进程池的使用。

okok Tue Sep 22 09:04:09 2020
okok ok Tue Sep 22 09:04:09 2020
 Tue Sep 22 09:04:09 2020
Tue Sep 22 09:04:09 2020
 Tue Sep 22 09:04:09 2020
ok Tue Sep 22 09:04:11 2020okokok Tue Sep 22 09:04:11 2020ok Tue Sep 22 09:04:11 2020
 Tue Sep 22 09:04:11 2020 

Tue Sep 22 09:04:11 2020

ok okok Tue Sep 22 09:04:13 2020
okTue Sep 22 09:04:13 2020
 Tue Sep 22 09:04:13 2020 Tue Sep 22 09:04:13 2020
ok
 Tue Sep 22 09:04:13 2020
ok Tue Sep 22 09:04:15 2020okokok Tue Sep 22 09:04:15 2020ok  Tue Sep 22 09:04:15 2020

 Tue Sep 22 09:04:15 2020

Tue Sep 22 09:04:15 2020

可以看到上面的执行结果并不是一次全部输出,而是断断续续的,当然了,可以看到输出的信息,里面有一次输出两条的原因是因为,我们并没有为我们的输出加一个锁,照成我们输出的时候,会有并发输出的现象,所以我们可以在这里为我们的输出加上一个锁。

from multiprocessing import Process, Semaphore, Lock, Queue
import time

buffer = Queue(10)
empty = Semaphore(2)
full = Semaphore(0)
lock = Lock()

class Consumer(Process):
    def run(self):
        global buffer, empty, full, lock
        while True:
            full.acquire()
            lock.acquire()
            buffer.get()
            print('Consumer pop an element')
            time.sleep(1)
            lock.release()
            empty.release()

class Producer(Process):
    def run(self):
        global buffer, empty, full, lock
        while True:
            empty.acquire()
            lock.acquire()
            buffer.put(1)
            print('Producer append an element')
            time.sleep(1)
            lock.release()
            full.release()

if __name__ == '__main__':
    p = Producer()
    c = Consumer()
    p.daemon = c.daemon = True
    p.start()
    c.start()
    p.join()
    c.join()
    print('Main Process Ended')

看我们的这个代码就是为我们的执行的操作加上了一个锁,就不会出现上面的那种一行,会有两个输出争抢。

先写到这,我也不知道怎么解决了,上面那个在linux上是可以运行得,但是在window上就不行了。我看了半天,原因是因为消费者拿到信号量full得时候,我们还没有给信号量full+1,此时得信号量full为0,所以他是阻塞得,所以想了一个办法,让他信号量full为0得时候,continnue,一下,我的想法是通过queue长度来判断我们是否break,但是我做到这里得时候,又出现一个问题,queue拿到得不是当前得全局得queue,明明queue此时在生产者得长度已经增加为2了,但是在消费者里面拿到得queue得长度还是为0,我想这个也应该是我们信号量full为0得原因把,要不然他也就执行了。有谁知道得可以告诉我一下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值