• 线程和进程


    操作系统/应用程序

    硬件,硬盘、cpu、主板、显卡、内存、电源... ...

    装系统(软件)

    系统就是由一个程序员写出来软件,该关键用于控制计算机的硬件,让他们之间进行相互配合

    软件安装(安装应用程序)

    qq  360  百度云   pycharm

    并发和并行

    并发,伪,由于执行速度特别快,人感觉不到停顿。

    并行,真,创建10个人同时操作。

    进程和线程

    单进程、单线程的应用程序

    print("666")
    

      到底什么是线程?什么是进程?

    Python自己没有这玩意,Python中调用的操作系统的线程和进程。

    单线程、多线程的应用程序

    import threading
    print("666")
    
    def func(arg):
          print(arg)
    t = threading.Thread(target=func)
    t.start()
    
    print("end")
    

     python线程编写

    import threading
    v1 = [11,22,33]
    v2 = [44,55,66]
    
    def func(data,plus):
         for i in range(len(data)):
              data[i] = data[i] + plus
    
    t1 = threading.Thread(target=func,args=(v1,1))
    t1.start()
    
    t2 = threading.Thread(target=func,args=(v2,100))
    t2.start()
    

    python锁

    python的GIL锁

    python内置一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被cpu调用

    线程锁:由于线程之间是进行随机调度,并且每个线程可能只执行n条执行之后,当多个线程同时修改同一条数据时可能会出现脏数据,所以,出现了线程锁 - 同一时刻允许一个线程执行操作。

     lock/Rlock   一次放1个

    import threading
    import time
    
    v = []
    lock = threading.Lock()
    
    def func(arg):
        lock.acquire()
        v.append(arg)
        time.sleep(0.01)
        m = v[-1]
        print(arg,m)
        lock.release()
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    
    v = []
    lock = threading.RLock()
    def func(arg):
        lock.acquire()
        lock.acquire()
    
        v.append(arg)
        time.sleep(0.01)
        m = v[-1]
        print(arg,m)
    
        lock.release()
        lock.release()
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    

      BoundedSemaphore(1次放N个)信号量

    import time
    import threading
    
    lock = threading.BoundedSemaphore(3)
    def func(arg):
        lock.acquire()
        print(arg)
        time.sleep(1)
        lock.release()
    
    
    for i in range(20):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    

      condition锁,一次放n个

    import time
    import threading
    
    lock = threading.Condition()
    
    # ############## 方式一 ##############
    
    def func(arg):
        print('线程进来了')
        lock.acquire()
        lock.wait() # 加锁
    
        print(arg)
        time.sleep(1)
    
        lock.release()
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    while True:
        inp = int(input('>>>'))
    
        lock.acquire()
        lock.notify(inp)
        lock.release()
    
    
    # ############## 方式二 ##############
    """
    def xxxx():
        print('来执行函数了')
        input(">>>")
        # ct = threading.current_thread() # 获取当前线程
        # ct.getName()
        return True
    
    def func(arg):
        print('线程进来了')
        lock.wait_for(xxxx)
        print(arg)
        time.sleep(1)
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    """
    

     锁Event    一次全部放  

    import time
    import threading
    
    lock = threading.Event()
    
    
    def func(arg):
        print('线程来了')
        lock.wait() # 加锁:红灯
        print(arg)
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    input(">>>>")
    lock.set() # 绿灯
    
    
    lock.clear() # 再次变红灯
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    input(">>>>")
    lock.set()
    

     为什么要加锁:

    非线程安全

    控制一段代码

    threading.local

    作用:内部自动为每个线程维护一个空间(字典),用于当前存取属于自己的值。保证线程之间的数据隔离。

     示例:

    import time
    import threading
    
    v = threading.local()
    def func(arg):
        # 内部会为当前线程创建一个空间用于存储:phone=自己的值
        v.phone = arg
        time.sleep(2)
        print(v.phone,arg) # 去当前线程自己空间取值
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    

      线程池

    生产者消费者模型

    三部件:

    生产者

    队列,先进先出

    扩展:栈,后进先出

    消费者

    问:生产者消费者模型解决了什么问题?

    不用一直等待的问题。

    import time
    import queue
    import threading
    q = queue.Queue() # 线程安全
    
    def producer(id):
        """
        生产者
        :return:
        """
        while True:
            time.sleep(2)
            q.put('包子')
            print('厨师%s 生产了一个包子' %id )
    
        for i in range(1,4):
            t = threading.Thread(target=producer,args=(i,))
            t.start()
    
    
        def consumer(id):
        """
        消费者
        :return:
        """
        while True:
            time.sleep(1)
            v1 = q.get()
            print('顾客 %s 吃了一个包子' % id)
    
        for i in range(1,3):
    	t = threading.Thread(target=consumer,args=(i,))
    	t.start()                
    

     

    进程 :

    进程间数据不共享

    data_list = []
    
    def task(arg):
        data_list.append(arg)
        print(data_list)
    
    
    def run():
        for i in range(10):
            p = multiprocessing.Process(target=task,args=(i,))
            # p = threading.Thread(target=task,args=(i,))
            p.start()
    
    if __name__ == '__main__':
        run()
    

     常用功能:

    join、deamon、name、multiprocessing.current_process()、multiprocessing.current_process().ident/pid

     类继承方式创建进程:

    import multiprocessing
    class MyProcess(multiprocessing.Process):
    
        def run(self):
            print('当前进程',multiprocessing.current_process())
    
    
    def run():
        p1 = MyProcess()
        p1.start()
    
        p2 = MyProcess()
        p2.start()
    
    if __name__ == '__main__':
        run()
    

      进程间数据共享:

    Queue:
    linux:
    	q = multiprocessing.Queue()
    
    	def task(arg,q):
    		q.put(arg)
    
    	def run():
    		for i in range(10):
    			p = multiprocessing.Process(target=task, args=(i, q,))
    			p.start()
    
    		while True:
    			v = q.get()
    			print(v)
    
    	run()
    windows:	
    def task(arg,q):
    	q.put(arg)
    
    if __name__ == '__main__':
    	q = multiprocessing.Queue()
    	for i in range(10):
    		p = multiprocessing.Process(target=task,args=(i,q,))
    		p.start()
    	while True:
    		v = q.get()
    		print(v)
    	
    Manager:(*)
    Linux:
    	m = multiprocessing.Manager()
    	dic = m.dict()
    
    	def task(arg):
    		dic[arg] = 100
    
    	def run():
    		for i in range(10):
    			p = multiprocessing.Process(target=task, args=(i,))
    			p.start()
    
    		input('>>>')
    		print(dic.values())
    		
    	if __name__ == '__main__':
    		
    		run()
    windows:
    	def task(arg,dic):
    		time.sleep(2)
    		dic[arg] = 100
    
    	if __name__ == '__main__':
    		m = multiprocessing.Manager()
    		dic = m.dict()
    
    		process_list = []
    		for i in range(10):
    			p = multiprocessing.Process(target=task, args=(i,dic,))
    			p.start()
    
    			process_list.append(p)
    
    		while True:
    			count = 0
    			for p in process_list:
    				if not p.is_alive():
    					count += 1
    			if count == len(process_list):
    				break
    		print(dic)
    

     进程锁

    import time
    import threading
    import multiprocessing
    
    
    lock = multiprocessing.RLock()
    
    def task(arg):
        print('鬼子来了')
        lock.acquire()
        time.sleep(2)
        print(arg)
        lock.release()
    
    
    if __name__ == '__main__':
        p1 = multiprocessing.Process(target=task,args=(1,))
        p1.start()
    
        p2 = multiprocessing.Process(target=task, args=(2,))
        p2.start()
    

      为什么要加锁??

    进程池

    import time
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    
    def task(arg):
        time.sleep(2)
        print(arg)
    
    if __name__ == '__main__':
    
        pool = ProcessPoolExecutor(5)
        for i in range(10):
            pool.submit(task,i)
    

      

     

     

  • 相关阅读:
    CSAPP DataLab
    《计算机网络自顶向下》第二章应用层,笔记总结
    计算机网络自顶向下第二章套接字编程作业
    第二章---信息的表示与处理
    python界面使用gbk编码
    python修改获取xlsx数据
    刚安装了ftp之后无法使用root访问,服务器发回了不可路由的地址。使用服务器地址代替。
    ssh_exchange_identification: read: Connection reset
    <七>对于之前的一些遗漏的地方的补充
    (六)单例模式与多线程时的安全问题以及解决办法
  • 原文地址:https://www.cnblogs.com/982336352ryan/p/9623376.html
Copyright © 2020-2023  润新知