Эта статья участвовала в приказе о созыве Haowen, нажмите, чтобы просмотреть:Двойные заявки на внутреннюю и внешнюю стороны, призовой фонд в 20 000 юаней ждет вас, чтобы бросить вызов!
Цель многопоточности в проекте
Конкретный принцип, я думаю, должен иметь возможность прыгать в операционную систему.Небольшое резюмеВы также можете найти книгу этой операционной системы.Если вы не можете найти старые правила, вы можете найти мою домашнюю страницу.Есть статья о ресурсах, которые содержат ресурсы.Конечно, вы также можете написать мне личное сообщение. Поговорим о цели использования многопоточности в нашем проекте: 1. Разделять память между потоками очень просто. 2. Использование многопоточности для одновременного выполнения нескольких задач более эффективно, чем использование нескольких процессов. 3. Иногда это может сэкономить время работы, что станет известно через некоторое время. 4. Многопоточность можно использовать, когда вы хотите одновременно выполнять несколько функций в одном файле.
python语言内置了多线程功能支持,而不是单纯地作为底层操作系统的调度方式,从而简化了python的多线程编程。
реальная боевая операция
Говорить так много не так хорошо, как на практике, сначала импортируйте поток
Особое внимание: когда вы видите файл, пожалуйста, не называйте импортированный пакет.threadingВ противном случае это пойдет не так.
Советы
import threading
Давайте теперь посмотрим на свои процедуры количество процессов
import threading
def main():
print(threading.current_thread())
if __name__ == '__main__':
main()
结果:1#我的就一个你的呢?
Если ваш процесс не один, вы также можете просмотреть имя каждого процесса, как это
import threading
def main():
print(threading.active_count())
print(threading.enumerate())
if __name__ == '__main__':
main()
>>>[<_MainThread(MainThread, started 36004)>]#返回的是一个列表因为我的目前就一个所以就一个主进程
Вы также можете просматривать запущенные процессы
import threading
def main():
print(threading.active_count())
print(threading.enumerate())
print(threading.current_thread())
if __name__ == '__main__':
main()
>1
[<_MainThread(MainThread, started 36004)>]
<_MainThread(MainThread, started 36004)>
Создайте простую цепочку
Сначала давайте представимthreading.Thread()Для параметров внутри лучше всего смотреть содержимое исходного файла при изучении функции каждого модуля python, что поможет улучшить ваши способности программирования:
Я отметил моменты, требующие внимания
import threading
def first():
print("frist active")
print("frist finish")
def main():
first_thread=threading.Thread(target=first,name="T1")
first_thread.start()#开始的标志
print("main")
if __name__ == '__main__':
main()
结果:
第一次运行
frist active
main
frist finish
第二次运行
frist active
frist finish
main
Разные результаты каждый раз уже говорят о том, что Frist и main работают одновременно. Если эффект не очевиден, давайте улучшим его, а затем введем
import time
import threading
import time
def first():
print("frist active")
time.sleep(3)
print("frist finish")
def main():
first_thread=threading.Thread(target=first,name="T1")
first_thread.start()
print("main")
if __name__ == '__main__':
main()
结果:
frist active
main
frist finish
Поскольку поток Frist спит в течение 3 секунд, когда Frist активен, основной поток все еще выполняется, так что это результат каждый раз.С особым акцентом наtarget=firstЭто не импорт функции Frist. Из исходного файла мы уже видели, что это выполняется с помощью метода run (). Для объяснения здесь я цитирую большого парня, чтобы объяснить.
Каждый должен быть знаком с этим боссом, то есть со знаменитым академическим комитетом Лея, вы можете перейти на его домашнюю страницу, чтобы узнать, можете ли вы узнать какие-то новые знания.
Конечно, вы можете переписать, если считаете, что этого недостаточно.threading.ThresdМетод запуска здесь для создания пользовательского потока
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()
结果:
task t1
task t2
2s
2s
1s
1s
0s
0s
Нить демона
所谓’线程守护’,就是主线程不管该线程的执行情况,只要是其他子线程结束且主线程执行完毕,主线程都会关闭。也就是说:主线程不等待该守护线程的执行完再去关闭。
Если вы не понимаете, давайте посмотрим на пример
import threading
import time
def first():
print("frist active")
time.sleep(3)
print("frist finish")
def second():
print("second active")
print("second finish")
def main():
first_thread=threading.Thread(target=first,name="T1")
second_thresd=threading.Thread(target=second,name="T2")
first_thread.setDaemon(True)#一定要在start()前开始
first_thread.start()
second_thresd.start()
print("main")
if __name__ == '__main__':
main()
结果
frist active
second active
second finishjiemeijieshu
main
Когда основной поток и другие дочерние потоки завершаются независимо от потока демонаfirst_threadКонец или не конец программа заканчивается
когда установленоsecond_thresdЭто относится к потоку демона
import threading
import time
def first():
print("frist active")
time.sleep(3)
print("frist finish")
def second():
print("second active")
print("second finish")
def main():
first_thread=threading.Thread(target=first,name="T1")
second_thresd=threading.Thread(target=second,name="T2")
second_thresd.setDaemon(True)#一定要在start()前开始
first_thread.start()
second_thresd.start()
print("main")
if __name__ == '__main__':
main()
frist active
second active
second finish
main
frist finish #尽管输出这个要等三秒
Основной процесс ожидает завершения дочернего процесса
Чтобы основной поток завершился после завершения выполнения потока демона, мы можем использовать метод соединения, чтобы позволить основному потоку дождаться выполнения дочернего потока.
import threading
import time
def first():
print("frist active")
time.sleep(3)
print("frist finish")
def second():
print("second active")
print("second finish")
def main():
first_thread=threading.Thread(target=first,name="T1")
second_thresd=threading.Thread(target=second,name="T2")
first_thread.start()
second_thresd.start()
first_thread.join()
print("main")
if __name__ == '__main__':
main()
结果:
frist active
second active
second finish
frist finish
main
不加join是这样的结果
frist active
second active
second finish
main
frist finish
Особенности общих глобальных переменных
Здесь определяется глобальная переменная A
import threading
import time
def first():
global A
print("frist active")
time.sleep(3)
A=A+3
print("frist:%d"%A)
print("frist finish")
def second():
global A
print("second active")
A=A+6
print("second:%d"%A)
print("second finish")
def main():
global A
first_thread=threading.Thread(target=first,name="T1")
second_thresd=threading.Thread(target=second,name="T2")
first_thread.start()
second_thresd.start()
#first_thread.join()
print("main")
A=A+3
print("mian:%d"%A)
if __name__ == '__main__':
A=0
main()
взгляните на результаты
frist active
second active
second:6
second finish
main
mian:9
frist:12
frist finish
Замок
Как видно из вышеприведенного примера, при выводе значения А происходит совместное использование ресурсов между разными процессами, что приводит к нестабильному значению переменной А и ситуации грязных данных, Если вы не понимаете, давайте брать пример.
При отсутствии блокировок взаимного исключения, при условии, что на счете есть 10 000 юаней, остаток на счете может составлять 11 000 юаней, если внесение и снятие денег выполняются одновременно. Так что, конечно, я счастлив, но банк не согласен. Чтобы избежать этой ситуации, мы вводим понятие блокировки.Ниже мы кратко представим несколько часто используемых программ.
Мьютекс
import threading
import time
def first():
global A,lock
lock.acquire()
print("frist active")
time.sleep(3)
A=A+3
print("frist:%d"%A)
print("frist finish")
lock.release()
def second():
global A,lock
lock.acquire()
print("second active")
A=A+6
print("second:%d"%A)
print("second finish")
lock.release
def main():
global A,lock
lock=threading.Lock()
first_thread=threading.Thread(target=first,name="T1")
second_thresd=threading.Thread(target=second,name="T2")
first_thread.start()
second_thresd.start()
#first_thread.join()
print("main")
A=A+3
print("mian:%d"%A)
if __name__ == '__main__':
A=0
main()
результат
frist active
main
mian:3
frist:6
frist finish
second active
second:12
second finish
Удобнее ли смотреть на это так, если пример недостаточно очевиден, давайте сделаем еще один
import threading
import time
def first():
global A,lock
lock.acquire()
print("frist active")
time.sleep(3)
A=A+3
print("frist1:%d"%A)
A = A + 3
print("frist2:%d" % A)
print("frist finish")
lock.release()
def second():
global A,lock
lock.acquire()
print("second active")
A=A+6
print("second1:%d"%A)
A=A+6
print("second2:%d"%A)
print("second finish")
lock.release()
def main():
global A,lock
lock=threading.Lock()
first_thread=threading.Thread(target=first,name="T1")
second_thresd=threading.Thread(target=second,name="T2")
first_thread.start()
second_thresd.start()
#first_thread.join()
print("main")
A=A+3
print("mian:%d"%A)
if __name__ == '__main__':
A=0
main()
результат
frist active
main
mian:3
frist1:6
frist2:9
frist finish
second active
second1:15
second2:21
second finish
去掉锁以后结果
frist active
second active
second1:6
second2:12
second finish
main
mian:15
frist1:18
frist2:21
frist finish
Очевидно, что после снятия блокировки результат будет очень грязным.
сигнал
Я полагаю, что у меня есть некоторое представление об операционной системе.Когда я только что упомянул блокировки, я подумал о семафорах.В конце концов, вопросы аспирантов часто возникают, синхронизация, взаимоисключение и семафорные механизмы. Поговорим о семафорных замках.На самом деле причина очень проста.Если ты сейчас женат в Китае,то можешь жениться только на одной жене.Хотя можно найти и других женщин,но женами их назвать нельзя.Их будут называть любовницами. , Любовница и т.д. Здесь семафор жены ==один == в китае может быть только один, а остальные не допустят.
import threading
import time
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(3) #最多允许3个线程同时运行
for i in range(10):
t = threading.Thread(target=run,args=('t-%s' % i,semaphore))
t.start()
while threading.active_count() !=1:
pass
else:
print('----------all threads done-----------')
результат
run the thread:t-2
run the thread:t-1
run the thread:t-0
run the thread:t-3
run the thread:t-5
run the thread:t-4
run the thread:t-6
run the thread:t-7
run the thread:t-8
run the thread:t-9
----------all threads done-----------
Отправить некоторые ресурсы
Фэй Сюэ считает, что эти операции в питоне все еще немного просты. Если вы хотите продолжить изучение темы и у вас нет ресурсов, вы можете получить книгу об операционной системе здесь. Вы можете написать мне лично, чтобы получить ее. Что ж , сегодняшнее обучение здесь. Не забывайте == Как тройка ==