Cet article vous apporte des connaissances pertinentes sur python. Il présente principalement la création et les méthodes courantes des threads, ainsi que quelques cas de démonstration de threads. J'espère qu'il sera utile à tout le monde.
Apprentissage recommandé : Tutoriel vidéo Python
Il existe de nombreux modules multi-threading en Python, parmi lesquels le module thread
ing est plus communément utilisé. Voyons comment utiliser thread
ing pour créer des threads et ses méthodes courantes. thread
ing 模块就是比较常用的。下面就来看一下如何利用 thread
ing 创建线程以及它的常用方法。
Création de fils de discussion - threading
函数名 介绍 举例 Thread 创建线程 Thread(target, args) Thread 的动能介绍:通过调用
threading
模块的Thread
类来实例化一个线程对象;它有两个参数:target 与 args
(与创建进程时,参数相同)。target
为创建线程时要执行的函数,而args
Nom de la fonctionIntroduction
getName()🎜🎜🎜 🎜setName 🎜 🎜Définir le nom du fil de discussion🎜🎜setName(name)🎜🎜🎜🎜is_alive🎜🎜Déterminer si le fil de discussion est vivant🎜🎜is_alive()🎜🎜🎜🎜setDaemon🎜🎜Daemon thread🎜 🎜setDaemon (Vrai)🎜 🎜 🎜🎜Thread Création de fils Exemples Thread (cible, arguments) Énergie cinétique du fil Introduction : Instancier un objet thread en appelant la classe Thread
du modulethreading
; il a deux paramètres :target et args
(similaire à la création d'un Processus, les paramètres sont les mêmes).target
est la fonction à exécuter lors de la création d'un thread, etargs
est les paramètres qui doivent être transmis lors de l'exécution de cette fonction.Méthodes courantes des objets thread Jetons un coup d'œil aux méthodes couramment utilisées dans les objets thread : Utilisation Nom de la fonction Introduction Démarrez le thread start Bloquer le fil jusqu'à la fin de l'exécution du fil start() join Obtenir le nom du fil join(timeout=None) getName
- fonction start : démarre un fil de discussion ; aucune valeur de retour ni paramètre.
- fonction join : identique à la fonction join dans le processus ; bloquant le programme en cours, la tâche du thread principal doit attendre la fin de la tâche du sous-thread actuel avant de pouvoir continuer à s'exécuter ; : représente le délai d'expiration du blocage.
timeout
:代表阻塞的超时时间。- getName 函数:获取当前线程的名字。
- setName 函数:给当前的线程设置名字;参数为
name
:是一个字符串类型- is_alive 函数:判断当前线程的状态是否存货
- setDaemon 函数:它是一个守护线程;如果脚本任务执行完成之后,即便进程池还没有执行完成业务也会被强行终止。子线程也是如此,如果希望主进程或者是主线程先执行完自己的业务之后,依然允许子线程继续工作而不是强行关闭它们,只需要设置
setDaemon()
为True
就可以了。PS:通过上面的介绍,会发现其实线程对象里面的函数几乎和进程对象中的函数非常相似,它们的使用方法和使用场景几乎是相同的。
演示 多线程之前
先看一下下面这个案例,运行结束后看看共计耗时多久
1、定义一个列表,里面写一些内容。
2、再定义一个新列表,将上一个列表的内容随机写入到新列表中;并且删除上一个列表中随机获取到的内容。
3、这里需要使用到
r andom
内置模块
代码示例如下:
# coding:utf-8import timeimport random old_lists = ['罗马假日', '怦然心动', '时空恋旅人', '天使爱美丽', '天使之城', '倒霉爱神', '爱乐之城']new_lists = []def work(): if len(old_lists) == 0: # 判断 old_list 的长度,如果为0 ,则表示 该列表的内容已经被删光了 return '\'old_list\' 列表内容已经全部删除' old_choice_data = random.choice(old_lists) # random 模块的 choice函数可以随机获取传入的 old_list 的元素 old_lists.remove(old_choice_data) # 当获取到这个随机元素之后,将该元素从 old_lists 中删除 new_choice_data = '%s_new' % old_choice_data # 将随机获取到的随机元素通过格式化方式重新赋值,区别于之前的元素 new_lists.append(new_choice_data) # 将格式化的新的随机元素添加至 new_lists 列表 time.sleep(1)if __name__ == '__main__': strat_time = time.time() for i in range(len(old_lists)): work() if len(old_lists) ==0: print('\'old_lists\' 当前为:{}'.format(None)) else: print(('\'old_lists\' 当前为:{}'.format(old_lists))) if not len(new_lists) == 0: print(('\'new_lists\' 当前为:{}'.format(new_lists))) else: print('\'new_lists\' 当前为:{}'.format(None)) end_time = time.time() print('运行结束,累计耗时:{} 秒'.format(end_time - strat_time))
运行结果如下:
从运行输出结果我们可以看到整个脚本运行共计耗时7秒,而且 new_lists
列表内的元素都经过格式化处理后加上了 _new
;不仅如此, 因为 random模块的choice函数
原因,new_lists
的内容顺序与 old_lists
也是不一样;每次运行顺序都会不一样,所以 old_lists
的顺序是无法得到保障的。
代码示例如下:
# coding:utf-8import timeimport randomimport threading old_lists = ['罗马假日', '怦然心动', '时空恋旅人', '天使爱美丽', '天使之城', '倒霉爱神', '爱乐之城']new_lists = []def work(): if len(old_lists) == 0: # 判断 old_list 的长度,如果为0 ,则表示 该列表的内容已经被删光了 return '\'old_list\' 列表内容已经全部删除' old_choice_data = random.choice(old_lists) # random 模块的 choice函数可以随机获取传入的 old_list 的元素 old_lists.remove(old_choice_data) # 当获取到这个随机元素之后,将该元素从 old_lists 中删除 new_choice_data = '%s_new' % old_choice_data # 将随机获取到的随机元素通过格式化方式重新赋值,区别于之前的元素 new_lists.append(new_choice_data) # 将格式化的新的随机元素添加至 new_lists 列表 time.sleep(1)if __name__ == '__main__': strat_time = time.time() print('\'old_lists\'初始长度为:{}'.format(len(old_lists))) # 获取 old_lists 与 new_lists 最初始的长度 print('\'new_lists\'初始长度为:{}'.format(len(new_lists))) thread_list = [] # 定义一个空的 thread_list 对象,用以下方添加每个线程 for i in range(len(old_lists)): thread_work = threading.Thread(target=work) # 定义一个线程实例化对象执行 work 函数,因为 work 函数没有参数所以不用传 args thread_list.append(thread_work) # 将 thread_work 添加进 thread_list thread_work.start() # 启动每一个线程 for t in thread_list: # 通过for循环将每一个线程进行阻塞 t.join() if len(old_lists) ==0: print('\'old_lists\' 当前为:{}'.format(None), '当前长度为:{}'.format(len(old_lists))) else: print(('\'old_lists\' 当前为:{}'.format(old_lists))) if not len(new_lists) == 0: print('\'new_lists\' 当前长度为:{}'.format(len(new_lists))) print('\'new_lists\' 当前的值为:{}'.format(new_lists)) else: print('\'new_lists\' 当前为:{}'.format(None)) end_time = time.time() print('运行结束,累计耗时:{} 秒'.format(end_time - strat_time))
运行结果如下:
从运行的结果来看,我们初始的单线程任务耗时为 7秒,在使用多线程之后,仅耗时 1秒就完成了,大大的提高了我们的运行效率。
通过上面的练习,我们发现线程的使用方法几乎与进程是一模一样的。它们都可以互不干扰的执行程序,也可以使得主线程的程序不需要等待子线程的任务完成之后再去执行。只不过刚刚的演示案例中我们使用了 join()
函数进行了阻塞,这里可以吧 join()
去掉,看看执行效果。
与进程一样,线程也存在着一定的问题。
关于这些线程中存在的问题同样是可以解决的,在下一章节的 线程池与全局锁
setDaemon(. )
à True
fera l'affaire. 🎜🎜PS : grâce à l'introduction ci-dessus, vous constaterez que les fonctions de l'objet thread sont presque très similaires aux fonctions de l'objet processus, et que leurs méthodes d'utilisation et scénarios d'utilisation sont presque les mêmes. 🎜Avant le multi-threading code> Jetons d'abord un coup d'œil au cas suivant. Après l'exécution, voyons combien de temps cela a pris au total🎜<blockquote>🎜1 Définissez une liste et écrivez-y du contenu. 🎜🎜2. Définissez une nouvelle liste, écrivez aléatoirement le contenu de la liste précédente dans la nouvelle liste et supprimez le contenu obtenu aléatoirement de la liste précédente. 🎜🎜3. Vous devez utiliser le module intégré <code>r andom
🎜🎜L'exemple de code est le suivant : 🎜rrreee🎜Les résultats d'exécution sont les suivants : 🎜🎜🎜D'après les résultats de sortie en cours d'exécution, nous pouvons voir que l'exécution du script entier prend 7 secondes et que les éléments de la liste new_lists
ont été formatés et ajoutés avec _new code> ; pas seulement cela, car <code>random La raison de la fonction de choix du module
est que l'ordre du contenu des new_lists
est également différent de celui des old_lists
; l'ordre sera différent à chaque exécution, donc old_lists
> L'ordre n'est pas garanti. 🎜
🎜🎜À partir des résultats en cours d'exécution , notre commande initiale La tâche de thread a pris 7 secondes après avoir utilisé le multi-threading, cela n'a pris que 1 seconde, ce qui a considérablement amélioré notre efficacité opérationnelle.
🎜
join()
pour bloquer. Vous pouvez supprimer join()
ici pour voir l'effet d'exécution. 🎜🎜Comme les processus, les threads ont également certains problèmes. 🎜🎜🎜La fonction exécutée par le thread ne peut pas non plus obtenir la valeur de retour. 🎜🎜Lorsque plusieurs threads modifient le fichier en même temps, cela entraînera également une confusion des données du fichier modifié (parce qu'ils exploitent tous un fichier simultanément, en particulier lorsqu'il s'agit de scénarios de transaction, vous devez prêter une attention particulière). 🎜🎜Les problèmes existant dans ces threads peuvent également être résolus. Nous les présenterons en détail dans le prochain chapitre de Thread Pool et Global Lock
. 🎜🎜Apprentissage recommandé : 🎜Tutoriel vidéo Python🎜🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!