冒泡泡de可乐
代码都是思想和概念的体现~每多学一点知识,就能少写一行代码~

进程:

         进程就是一组资源的集合

         线程是在进程里面干活的

        一个进程里面至少有一个线程,这个线程就是主线程

电脑CPU是几核的就只能同时运行几个任务(线程)

python里面的多线程其实只能用一个核

GIL  全局解释器锁

锁:多线程同时操作同一数据时必须加锁

CPU密集型任务 (CPU干活)   -----多进程

IO密集型任务(磁盘IO、网络IO)-----多线程

 

启动多线程、主线程等待子线程结束

#进程就是一组资源的集合
# 线程是在进程里面具体干活的

import threading
import time

def run():
    time.sleep(5)
    print('over')

start_time = time.time()
for i in range(20):  #需要多少个线程循环多少次
    t = threading.Thread(target=run)  #实例化一个线程
    t.start()  #启动这个线程

print('运行的时候有几个活跃线程',threading.activeCount())  #21   threading.activeCount() 当前有多少个线程在活跃

# while循环--主线程等待子线程运行结束
while threading.activeCount() !=1:  #当所有的子进程都结束时,只剩一个主线程
    pass

print('现在几个活跃线程',threading.activeCount())   #1
ent_time = time.time()
print(ent_time-start_time)


# for循环--主线程等待子线程运行结束
'''
start_time = time.time()
ths = []
for i in range(20):  #需要多少个线程循环多少次
    t = threading.Thread(target=run)  #实例化一个线程
    t.start()  #启动这个线程
    # t.join()  #在这里加join,线程就变成串行的了
    ths.append(t)  #建一个list,把每个已启动的线程存起来

for thread in ths:
    thread.join()   #循环等待每个线程结束

ent_time = time.time()
print(ent_time-start_time)  #5.004632949829102
'''

继承Thread类的方法启动多线程

import threading
import time

class MyThread(threading.Thread):  #继承Tread类
    def run(self): #这个方法必须叫run  重写父类run方法
        time.sleep(5)
        print('run')

for i in range(5):
    t = MyThread()   #实例化一个线程
    t.start()    #start()方法启动线程

获取多线程的返回值

import requests
import threading

all_res = []  #定义一个list,保存所有的返回结果
def get_name(name):
    r = requests.get('http://api.nnzhp.cn/api/user/stu_info?stu_name=%E5%B0%8F%E9%BB%91',
                     params=name)
    res = r.json()
    all_res.append(res)  #将这次请求的返回结果保存到 all_res中

for i in range(10):
    t = threading.Thread(target=get_name,args=(i,))
    t.start()

while threading.activeCount()!= 1:
    pass

print(all_res)

守护线程

#主线程 : 秦始皇
#守护线程:秦始皇修护陵墓的人

import threading
import time

def hhh():
    time.sleep(5)
    print('hhh')

for i in range(100):
    t = threading.Thread(target=hhh)
    t.setDaemon(True)   #设置子线程为守护线程  主线程死的时候,守护线程也得死
    t.start()

print('秦始皇死了')

import threading

num = 0   #全局变量
lock =threading.Lock() #申请一把锁 多线程同时操作同一个数据的时候一定要加锁

def xiaojun():
    global num   #想要修改全局变量,先声明它是global类型
    # lock.acquire() #加锁
    # num += 1
    # lock.release() #解锁   只加锁不解锁会导致死锁
    with lock: #with自动管理上下文 不需自己手动加锁/解锁
        num+=1

for i in range(100):
    t = threading.Thread(target=xiaojun)
    t.start()

while threading.activeCount()!=1:
    pass

print(num)

多进程

from multiprocessing import Process
import time
import threading

'''启动10个进程,每个进程启动10个线程'''

def run_thread(): time.sleep(60) print('%s在运行'%threading.current_thread()) #threading.current_thread() 当前线程名 def run(): for i in range(10): t = threading.Thread(target=run_thread) t.start() if __name__ =='__main__': for i in range(10): p = Process(target=run) #实例化一个进程 p.start() #启动进程 print(p.pid) #打印进程号

 队列- Queue

Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递

join()

阻塞调用线程,直到队列中的所有任务被处理掉。

只要有数据被加入队列,未完成的任务数就会增加。当消费者线程调用task_done()(意味着有消费者取得任务并完成任务),未完成的任务数就会减少。当未完成的任务数降到0,join()解除阻塞。

put(item[, block[, timeout]])

将item放入队列中。

  1. 如果可选的参数block为True且timeout为空对象(默认的情况,阻塞调用,无超时)。
  2. 如果timeout是个正整数,阻塞调用进程最多timeout秒,如果一直无空空间可用,抛出Full异常(带超时的阻塞调用)。
  3. 如果block为False,如果有空闲空间可用将数据放入队列,否则立即抛出Full异常

其非阻塞版本为put_nowait等同于put(item, False)

get([block[, timeout]])

从队列中移除并返回一个数据。block跟timeout参数同put方法

其非阻塞方法为`get_nowait()`相当与get(False)

empty()

如果队列为空,返回True,反之返回False

 

from multiprocessing import Process,Queue
import os, time, random

#写数据进程执行的代码
def write(q):
    for value in ['A','B','C']:
        print('Put %s to queue...'%value)
        q.put(value)
        time.sleep(random.random())

#读数据进程执行的代码
def read(q):
    while True:
        if not q.empty():
            value = q.get(True)
            print('Get %s from queue.'%value)
            time.sleep(random.random())
        else:
            break

if __name__ == '__main__':
    #父进程创建Queue,并传给各个子进程
    q = Queue()
    pw =Process(target=write,args=(q,))
    pr = Process(target=read,args=(q,))
    #启动子进程pw,写入
    pw.start()
    #等待pw结束
    pw.join()
    #启动子进程pr,读取:
    pr.start()
    pr.join()
    #pr进程里是死循环,无法等待其结束,只能强行终止
    print('')
    print('所有数据都写入并且读完')

 

posted on 2018-11-18 16:15  HathawayLee  阅读(198)  评论(0编辑  收藏  举报