# coding=utf-8
import threading
import time
#
'''
1、普通创建方式
'''
# def run(n):
# print(n)
# time.sleep(1)
# print('2s')
# time.sleep(1)
# print('1s')
# time.sleep(1)
# print('0s')
# time.sleep(1)
#
#
# if __name__ == '__main__':
# # target是要执行的函数名(不是函数),args是函数对应的参数,以元组的形式存在
# t1 = threading.Thread(target=run, args=('任务1',))
# t2 = threading.Thread(target=run, args=('任务2',))
# t1.start()
# t2.start()
'''
2、自定义线程:继承threading.Thread来定义线程类,
其本质是重构Thread类中的run方法,实例化参数
'''
# class MyThread(threading.Thread):
# def __init__(self, n):
# super(MyThread, self).__init__() # 重构run函数必须写
# self.n = n
#
# def run(self):
# print('task', self.n)
# time.sleep(1)
# print('2s')
# time.sleep(1)
# print('1s')
# time.sleep(1)
# print('0s')
# time.sleep(1)
#
#
# if __name__ == '__main__':
# t1 = MyThread('t1')
# t2 = MyThread('t2')
# t1.start()
# t2.start()
'''
3、守护线程
下面这个例子,这里使用setDaemon(True)把所有的子线程都变成了主线程的守护线程,
因此当主线程结束后,子线程也会随之结束,所以当主线程结束后,整个程序就退出了。
所谓’线程守护’,就是主线程不管守护线程的执行情况,只要是其他非守护子线程结束且主线程执行完毕,
主线程都会关闭。也就是说:主线程不等待守护线程的执行完再去关闭。
主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。
因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,
而进程必须保证非守护线程都运行完毕后才能结束。
'''
# def run(n):
# print('task', n)
# time.sleep(1)
# print('3s')
# time.sleep(1)
# print('2s')
# time.sleep(1)
# print('1s')
#
#
# if __name__ == '__main__':
# t = threading.Thread(target=run, args=('t1',))
# t.setDaemon(True)
# t.start()
# print('end')
'''
4、主线程等待子线程结束
为了让守护线程执行结束之后,主线程再结束,我们可以使用join方法,让主线程等待守护线程执行完毕再结束。
'''
# def run(n):
# print('task', n)
# time.sleep(2)
# print('5s')
# time.sleep(2)
# print('3s')
# time.sleep(2)
# print('1s')
#
#
# if __name__ == '__main__':
# t = threading.Thread(target=run, args=('t1',))
# t.setDaemon(True) # 把子线程设置为守护线程,必须在start()之前设置
# t.start()
# t.join() # 设置主线程等待子线程结束
# print('end')
'''
5、多线程共享全局变量
线程是进程的执行单元,进程是系统分配资源的最小执行单位,所以在同一个进程中的多线程是共享资源的。
'''
# g_num = 100
#
#
# def work1():
# global g_num
# for i in range(3):
# g_num += 1
# print('in work1 g_num is : %d' % g_num)
#
#
# def work2():
# global g_num
# print('in work2 g_num is : %d' % g_num)
#
#
# if __name__ == '__main__':
# t1 = threading.Thread(target=work1)
# t1.start()
# time.sleep(1)
# t2 = threading.Thread(target=work2)
# t2.start()
'''
6、互斥锁(Lock)
由于线程之间是进行随机调度,当多个线程同时修改同一条数据时可能会出现脏数据,
所以出现了线程锁,即同一时刻只允许一个线程执行某些操作。
线程锁用于锁定资源,可以定义多个锁,像下面的代码,当需要独占某一个资源时,
任何一个锁都可以锁定这个资源,就好比你用不同的锁都可以把这个相同的门锁住一样。
由于线程之间是进行随机调度的,如果有多个线程同时操作一个对象,
如果没有很好地保护该对象,会造成程序结果的不可预期,也称为“线程不安全”。
为了防止上面情况的发生,就出现了互斥锁(Lock)
'''
# def work():
# global n
# lock.acquire()
# temp = n
# time.sleep(0.1)
# n = temp - 1
# lock.release()
#
#
# if __name__ == '__main__':
# lock = threading.Lock()
# n = 100
# l = []
# for i in range(100):
# p = threading.Thread(target=work)
# l.append(p)
# p.start()
# # print l
# for p in l:
# p.join()
'''
7、递归锁:RLcok类的用法和Lock类一模一样,但它支持嵌套。
RLock类代表可重入锁(Reentrant Lock)。
对于可重入锁,在同一个线程中可以对它进行多次锁定,
也可以多次释放。如果使用 RLock,那么 acquire() 和 release() 方法必须成对出现。
如果调用了 n 次 acquire() 加锁,则必须调用 n 次 release() 才能释放锁。
由此可见,RLock 锁具有可重入性。也就是说,同一个线程可以对已被加锁的 RLock 锁再次加锁,
RLock 对象会维持一个计数器来追踪 acquire() 方法的嵌套调用,
线程在每次调用 acquire() 加锁后,都必须显式调用 release() 方法来释放锁。
所以,一段被锁保护的方法可以调用另一个被相同锁保护的方法。
'''
# def func(lock):
# global gl_num
# lock.acquire()
# gl_num += 1
# time.sleep(1)
# print gl_num
# lock.release()
#
#
# if __name__ == '__main__':
# gl_num = 0
# lock = threading.RLock()
# for i in range(10):
# t = threading.Thread(target=func, args=(lock,))
# t.start()
'''
8、信号量(BoundedSemaphore类)
互斥锁同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据,
比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去
'''
#
# def run(n, semaphore):
# semaphore.acquire() # 加锁
# time.sleep(3)
# print('run the thread:%s\n' % n)
# semaphore.release() # 释放
#
#
# if __name__ == '__main__':
# num = 0
# semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行
# for i in range(22):
# t = threading.Thread(target=run, args=('t-%s' % i, semaphore))
# t.start()
# while threading.active_count() != 1:
# pass
# else:
# print('----------all threads done-----------')
#多进程
# import multiprocessing
# import time
#
#
# def drink():
# for i in range(3):
# print("111……")
# time.sleep(1)
#
#
# def eat():
# for i in range(3):
# print("222……")
# time.sleep(1)
#
#
# if __name__ == '__main__':
# # target:指定函数名
# drink_process = multiprocessing.Process(target=drink)
# eat_process = multiprocessing.Process(target=eat)
# drink_process.start()
# eat_process.start()
import time
import multiprocessing
def eat(num, name):
for i in range(num):
print(name + "123……")
time.sleep(1)
def drink(num, name):
for i in range(num):
print(name + "321……")
time.sleep(1)
if __name__ == '__main__':
# target:指定执行的函数名
# args:使用元组方式给指定任务传参
# kwargs:使用字典方式给指定任务传参
eat_process = multiprocessing.Process(target=eat, args=(3, "gogogo"))
drink_process = multiprocessing.Process(target=drink, kwargs={"num": 4, "name": "giao"})
eat_process.start()
drink_process.start()
python多进程多线程代码学习
最新推荐文章于 2023-02-17 09:28:11 发布