欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python爬虫-全局的资源访问问题

程序员文章站 2024-01-22 23:26:34
...

python爬虫-全局的资源访问问题

概述

为了解决全局的变量的问题,线程不同步。

线程锁的使用

代码1

#在使用多线程的情况下,会使用到全局变量
import threading

gmoney=0
lock=threading.Lock()
def creater():
    global gmoney
    lock.acquire()
    for i in range(1000000):
        gmoney+=1
    lock.release()
    print(gmoney)
    return gmoney
def consumer():
    global gmoney
    lock.acquire()
    for i in range(1000000):
        gmoney+=1
    print(gmoney)
    lock.release()
    return gmoney


if __name__ == '__main__':
    threading.Thread(target=creater).start()
    threading.Thread(target=consumer).start()

代码2:

import threading
import time
import random

money=0
lock=threading.Lock()
gtime=0

class Product(threading.Thread):
    def run(self) -> None:
        global money
        global gtime
        while True:
            lock.acquire()
            num=random.randint(0,100)
            money+=num
            print(threading.current_thread().name,'生产了','%d元'%num,'当前的总额为',money)
            lock.release()
            time.sleep(1)
            gtime+=1
            if gtime>=100:
                return



class consumer(threading.Thread):
    def run(self) -> None:
        global money
        while True:
            lock.acquire()
            num=random.randint(1,100)
            if money<num:
                print('余额不足无法消费')
                lock.release()
                time.sleep(1)
                continue
            money-=num
            print(threading.current_thread().name,'消费了','%d元'%num,'当前的总额为',money)
            lock.release()
            time.sleep(1)



def main():
    for i in range(5):
        th=Product(name="生产者%d"%i)
        th.start()
    for i in range(5):
        th=consumer(name="消费者%d"%i)
        th.start()

if __name__ == '__main__':
    print(threading.enumerate())
    main()

使用conditoin

提供了休眠的方式,减少浪费cpu的资源

import threading
import time
import random

money=0
gdondition=threading.Condition()
gtime=0

class Product(threading.Thread):
    def run(self) -> None:
        global money
        global gtime
        while True:
            gdondition.acquire()
            num=random.randint(0,100)
            money+=num
            print(threading.current_thread().name,'生产了','%d元'%num,'当前的总额为',money)
            gdondition.notify_all()
            gdondition.release()
            time.sleep(1)
            gtime+=1
            if gtime>=100:
                return



class consumer(threading.Thread):
    def run(self) -> None:
        global money
        while True:
            gdondition.acquire()
            num=random.randint(1,100)
            while money<num:
                print('余额不足无法消费,%s正在等待资源中'%threading.current_thread().name)
                gdondition.wait()
            money-=num
            print(threading.current_thread().name,'消费了','%d元'%num,'当前的总额为',money)
            gdondition.release()
            time.sleep(1)



def main():
    for i in range(5):
        th=Product(name="生产者%d"%i)
        th.start()
    for i in range(5):
        th=consumer(name="消费者%d"%i)
        th.start()

if __name__ == '__main__':
    print(threading.enumerate())
    main()

使用队列的方式

from queue import Queue
import time

q=Queue(3)
# for i in range(2):
#     q.put(i)
q.empty()  #判断是否为空

# 超过队列的容量,对阻塞,如果不需要
for i in range(4):
    try:
        q.put(i,block=False)
    except:
        print('error')

print("done")
print(q.qsize())  # 取决与你放进去的元素的多少

def addvalue(q):
    for i in range(100):
        q.put(i,block=False)
        print("生产者生产了%d"%i)
        time.sleep(1)

def getValue(q):
    for i in range(100):
      a=q.get()
      print("消费者获取到了%d"%a)

import threading
if __name__ == '__main__':
    q=Queue(100)
    threading.Thread(target=addvalue,args=[q]).start()
    threading.Thread(target=getValue,args=[q]).start()