多线程和多进程

一、多线程  threading模块

# 线程和进程

'''

1.线程是最小的调度单位

2.进程是最小的管理单元

3.一个进程必须至少一个线程

4.没有线程,进程也就不复存在

'''

# 多线程特点:

# python线程特点

#线程的并发是利用cpu上下文的切换(是并发,不是并行)

#多线程执行的顺序是无序的

# def test1(n):
#     time.sleep(1)
#     print('task', n)
#
# # t1 = threading.Thread(target=test1,args=(1,))
# # t1.start()
#
# for i in range(10):
#     t = threading.Thread(target=test1,args=('t-%s' % i,))#args:传递的参数!
#     t.start()

#多线程共享全局变量,但是在使用之前要声名

# g = 0
# def test1():
#     global g
#     for i in range(10):
#         g += 1
#     print(g)
# def test2():
#     global g
#     for i in range(10):
#         g += 1
#     print(g)
#
# t1 = threading.Thread(target=test1)  #target=test1:建立线程时的调用对象是test1
# t2 = threading.Thread(target=test2)
# t1.start()
# t2.start()

#线程是继承在进程里的,没有进程就没有线程

#GIL全局解释器锁:

当运行如下代码时,运行结果会出现错误,

import threading
lock = threading.Lock()
global_num = 0
def test1():
    global global_num

    for i in range(1000000):
        global_num += 1

def test2():
    global global_num

    for i in range(1000000):
        global_num += 1

t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()
t1.join()
t2.join()
print(global_num)

这是因为:

1,主线程运行时间太短,调用函数的t1,t2两个线程,还没有运行完,主线程就已经运行结束了

2.有GIL全局解释器存在的原因,导致错误

# lock = threading.Lock()
# global_num = 0
# def test1():
#     global global_num
#     lock.acquire()
#     for i in range(1000000):
#         global_num += 1
#     lock.release()
# def test2():
#     global global_num
#     lock.acquire()
#     for i in range(1000000):
#         global_num += 1
#     lock.release()
# t1 = threading.Thread(target=test1)
# t2 = threading.Thread(target=test2)
# t1.start()
# t2.start()
# t1.join()
# t2.join()
# print(global_num)

解决的方法:

1.要使用join方法,以保证各个进程运行完

2.申请一个用户锁,将代码锁定,等到锁定的代码执行完毕之后再释放GIL全局解释器锁

#在IO密集型的代码里,适合用多线程

二、多进程  multiprocessing模块

#一个程序运行起来之后,代码+用到的资源称之为进程,它是操作系统分配资源的基本单位,不仅可以通过线程完成多任务,进程也是可以的

#进程之间是相互独立的

#cpu密集的时候适合用多进程

import multiprocessing
import time
# g = 0
# def test1(n):
#     time.sleep(50)
#     global g
#     for i in range(10):
#         g += 1
#     print(g)
# def test2(n):
#     time.sleep(50)
#     global g
#     for i in range(10):
#         g += 1
#     print(g)
# # test1(1)
# # test2(2)
# if __name__ == '__main__':
#     p1 = multiprocessing.Process(target=test1,args=(1,))
#     p2 = multiprocessing.Process(target=test2,args=(2,))
#     p1.start()
#     p2.start()



#进程池
# import multiprocessing
# from multiprocessing import Pool
# import time
# import threading
# g_num = 0
# def test1(n):
#     for i in range(n):
#         time.sleep(1)
#         print('test1', i)
#
# def test2(n):
#     for i in range(n):
#         time.sleep(1)
#         print('test2', i)
# def test3(n):
#     for i in range(n):
#         time.sleep(1)
#         print('test3', i)
#
# def test4(n):
#     for i in range(n):
#         time.sleep(1)
#         print('test4', i)
#
# if __name__ == '__main__':
#     pool = Pool(1)#把进程声明出来,括号里不写东西说明无限制,如果写数字,就是最大的进程数
#     pool.apply_async(test1,(10,))#用pool去调用函数test1,参数为10格式为(10,)
#     pool.apply_async(test2,(10,))#用pool去调用函数test2,参数为10格式为(10,)
#     pool.apply_async(test3,(10,))#用pool去调用函数test3,参数为10格式为(10,)
#     pool.apply_async(test4,(10,))#用pool去调用函数test4,参数为10格式为(10,)
#     pool.close()  # close必须在join的前面
#     pool.join()

  

原文地址:https://www.cnblogs.com/leeeel/p/10815785.html