python线程和进程,生产者消费者模型

应用程序像工厂,进程像车间,线程像工人

一个进程中的线程可以在不同cpu上执行,一个线程不能同时在两个cpu上执行

python中有一个全局解释器锁(GIL global interpreter lock),他就像一把锁所在进程上,保证同一时刻,一个进程中无论有多少线程,只能保证有一个线程出来

随着cpu核数的增加,python中可以创建多个进程,一个进程中有一个全局解释器,这样一个cpu跑一个进程,一个进程同一时刻只能出一个线程,达到并行的目的

线程和进程的区别 :
线程是可以共享内存的,而进程不可以共享内存,一个进程就像一个应用程序,例如qq和淘宝,这属于两个进程,在QQ中发信息肯定不会发到淘宝中,但是在qq中存在很多的线程,他们可以共享内存,他们都属于一个进程,
假如eclipse在运行时占中400M的内存空间,那么这个进程下的线程的共享空间为这个主进程所占用的内存空间,就是eclipse的线程的内存共享就为400M

线程没有办法单独执行,线程必须在进程中

多进程之间的通信
多进程之间无法直接通信,它必须借助一个第三方的桥梁
1 队列

from multiprocessing import Process, Queue 
def f(q,n): 
    q.put([ n, 'hello']) 
if __name__ == '__main__':
    q = Queue()

for i in range(5): 
        p = Process(target=f, args=(q,i)) 
        p.start() 
        print q.get() 

线程的安全问题,假如现在有十个线程,同时修改一个变量,让这个变量+1,那么会出现一个问题,假如A线程正在修改变量,现在变量为m=2,A线程操作m,目的是让A+1,然而A修改到一半的时候,线程B又进来了,线程B此时取的m的值也是2,A修改完了m=3,B修改完了m还是等于3 ,非常不安全
解决办法,就是加一把锁,形象的例子:
假如现在有10个人要上厕所,钥匙在我手里,这个时候A进来,他把门关上了,别人就进不去,只有等A完事后其他人才能进来,这个门就是控制线程的那把锁

代码实现就通过一个lock来实现,lock 只允许一个线程访问

lock=threading.Lock()
lock.acquire()
lock.release()

代码如下

val=0    #全局变量
def run(self,):
    #lock.acquire()
    time.sleep(1)
    global val 
    lock.acquire()
    val+=1
    print '%s' %val
    lock.release()        //这个地方执行完了必须relese,让后面的线程继续执行,否则后面无法执行

lock=threading.Lock()
for i in range(100):
    t=threading.Thread(target=run,args=(i,))
    t.start()

假如一个厕所门里有两个坑,允许两个人同时上厕所,即允许两个线程同时修改变量,那么用samp

samp = threading.BoundedSemaphore(3)
samp.acquire()
samp.release()

当参数为1时,实际上就等于lock

val=0    #全局变量
def run(self,):
    #lock.acquire()
    time.sleep(1)
    global val 
    samp.acquire()
    val+=1
    print '%s' %val
    samp.release()

lock=threading.Lock()
samp = threading.BoundedSemaphore(3)
for i in range(100):
    t=threading.Thread(target=run,args=(i,))
    t.start()

全局变量和局部变量
全局变量是在方法之外定义的变量,方法内部不能修改全局变量
例如 val=0 #全局变量
def run(self,n)
val+=1
程序会报错,方法内不能直接就该全局变量

在假如 val=0 #全局变量
def run(self,n)
val=1
print val
输出结果会是1,这是为什么呢,应为此时函数内部的val与全局变量val并不是一个,函数内部的 val是局部变量,函数外部的val为全局变量
假如 执行c=run(‘haha’)
print val
会输出 0
1

假如要在函数内重新定义局部变量
必须在函数中重新声明全局变量

val=0   #全局变量
    def run(self,n)
       global val
        val=1
       print val 

join() 执行到join时,例如执行到join(3)然后就在这个地方等待三秒,

from threading import Thread
import time
class MyThread(Thread):
    def run(self):
        time .sleep(5)
        print '我是线程'
def bar():
    print 'bar'

t1=MyThread(target=bar )
t1.start()
t1.join(3)
print ‘over'

生产者和消费者模型

http://www.cnblogs.com/bizhu/archive/2012/05/17/2506202.html 比较好的网址

采用面向类的生产者消费者模型

#_*_ coding:utf-8 _*_
from threading import Thread 
from Queue import Queue
import time
class Producer(Thread):
    def __init__(self,name,queue):
        self.__name=name
        self.__queue=queue
        super(Producer,self).__init__()                 #重写了父类的方法
    def run(self):
        while True:
            if self.__queue.full():
                time.sleep(1)
            else :
                self.__queue.put('baozi')
                time.sleep(1)
                print '%s生产了一个包子'%(self.__name)


class consumer(Thread):
    def __init__(self,name,queue):
        self.__name=name
        self.__queue=queue
        super(consumer,self).__init__()
    def run(self):
        while True:
            if self.__queue.empty():
                time.sleep(1)
            else :
                self.__queue.get()
                time.sleep(1)
                print '%s 消费一个包子'%(self.__name,)

que =Queue(maxsize=100)
baozi_make1=Producer('mahzongyi',que)
baozi_make1.start()
baozi_make2=Producer('mahzongyi1',que)
baozi_make2.start()
baozi_make3=Producer('mahzongyi2',que)
baozi_make3.start()
for item in range(20):
    name = 'lazup%d'%(item)
    temp=consumer(name,que)
    temp.start()
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值