>  기사  >  백엔드 개발  >  Python 스레드의 생성 및 일반적인 방법(자세한 예)

Python 스레드의 생성 및 일반적인 방법(자세한 예)

WBOY
WBOY앞으로
2022-05-06 18:41:183502검색

이 글은 python에 대한 관련 지식을 제공합니다. 주로 스레드 생성 및 일반적인 방법을 소개하고 일부 스레드 시연 사례를 함께 살펴보겠습니다.

Python 스레드의 생성 및 일반적인 방법(자세한 예)

추천 학습: python 비디오 튜토리얼

스레드 생성 및 사용

Python에는 많은 멀티 스레딩 모듈이 있으며 그 중 스레드 모듈이 더 일반적입니다. 사용된. threading을 사용하여 스레드를 생성하는 방법과 일반적인 메서드를 살펴보겠습니다. threading 模块就是比较常用的。下面就来看一下如何利用 threading 创建线程以及它的常用方法。

线程的创建 -threading

函数名 介绍 举例
Thread 创建线程 Thread(target, args)

Thread 的动能介绍:通过调用 threading 模块的 Thread 类来实例化一个线程对象;它有两个参数: target 与 args (与创建进程时,参数相同)。target 为创建线程时要执行的函数,而 args

스레드 생성 - threading

함수 이름소개Thread스레드 생성스레드의 운동 에너지 소개: threading 모듈의 Thread 클래스를 호출하여 스레드 개체를 인스턴스화합니다. 이 클래스에는 target 및 args라는 두 개의 매개변수가 있습니다. process , 매개변수는 동일합니다). target은 스레드 생성 시 실행되는 함수이고, args는 이 함수 실행 시 전달해야 하는 매개변수입니다. 스레드 객체의 일반적인 메서드사용법 시작 thread스레드 실행이 끝날 때까지 스레드를 차단합니다스레드 이름 가져오기
스레드 (target, args)
스레드 객체에서 일반적으로 사용되는 메서드를 살펴보겠습니다.
함수 이름 소개
시작
start() join
join(timeout=None) getName
getName()🎜🎜🎜 🎜setName 🎜 🎜스레드 이름 설정🎜🎜setName(이름)🎜🎜🎜🎜is_alive🎜🎜스레드가 살아 있는지 확인🎜🎜is_alive()🎜🎜🎜🎜setDaemon🎜🎜데몬 스레드🎜 🎜set데몬(참)🎜 🎜 🎜🎜
  • start 함수: 스레드를 시작합니다. 반환 값이나 매개변수가 없습니다.
  • join 함수: 현재 프로그램을 차단하는 프로세스의 Join 함수와 동일하게, 메인 스레드의 작업은 계속 실행되기 전에 현재 하위 스레드의 작업이 끝날 때까지 기다려야 합니다. 매개변수는 timeout입니다. : 차단 시간 초과 기간을 나타냅니다. 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))

运行结果如下:


Python 스레드의 생성 및 일반적인 방법(자세한 예)

从运行输出结果我们可以看到整个脚本运行共计耗时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))

运行结果如下:


Python 스레드의 생성 및 일반적인 방법(자세한 예)

从运行的结果来看,我们初始的单线程任务耗时为 7秒,在使用多线程之后,仅耗时 1秒就完成了,大大的提高了我们的运行效率。


 线程的问题

通过上面的练习,我们发现线程的使用方法几乎与进程是一模一样的。它们都可以互不干扰的执行程序,也可以使得主线程的程序不需要等待子线程的任务完成之后再去执行。只不过刚刚的演示案例中我们使用了 join() 函数进行了阻塞,这里可以吧 join() 去掉,看看执行效果。

与进程一样,线程也存在着一定的问题。

  • 线程执行的函数,也同样是无法获取返回值的。
  • 当多个线程同时修改文件一样会造成被修改文件的数据错乱的错误(因为都是并发去操作一个文件,特别是在处理交易场景的时候,需要尤为注意)。

关于这些线程中存在的问题同样是可以解决的,在下一章节的 线程池与全局锁

getName 함수: 현재 스레드의 이름을 가져옵니다.

setName 함수: 현재 스레드의 이름을 설정합니다. 매개변수는 name입니다. 문자열 유형입니다.

is_alive 함수: 현재 스레드의 상태가 재고인지 확인합니다. 🎜🎜setDaemon 함수 : 데몬 스레드입니다. ; 스크립트 작업이 실행되면 프로세스 풀이 해당 작업을 완료하지 않았더라도 강제 종료됩니다. 하위 스레드의 경우에도 마찬가지입니다. 기본 프로세스나 기본 스레드가 자체 작업을 먼저 완료하고 하위 스레드가 강제로 닫히는 대신 계속 작동하도록 하려면 setDaemon( ) True로 설정하면 문제가 해결됩니다. 🎜🎜PS: 위의 소개를 통해 스레드 개체의 기능이 프로세스 개체의 기능과 거의 매우 유사하며 사용 방법과 사용 시나리오도 거의 동일하다는 것을 알 수 있습니다. 🎜

스레드 데모 사례

단일 스레드 초기 사례

🎜Demo 멀티 스레드 전 code> 먼저 다음 사례를 살펴보겠습니다. 실행 후 총 시간이 얼마나 소요되는지 살펴보겠습니다.🎜<blockquote>🎜1. 목록을 정의하고 내용을 작성합니다. 🎜🎜2. 새 목록을 정의하고 이전 목록의 내용을 새 목록에 무작위로 쓴 다음 이전 목록에서 무작위로 얻은 내용을 삭제합니다. 🎜🎜3. 내장 모듈인 <code>r andom 을 사용해야 합니다🎜🎜코드 예시는 다음과 같습니다. 🎜rrreee🎜실행 결과는 다음과 같습니다. 🎜

Python 스레드의 생성 및 일반적인 방법(자세한 예)🎜🎜실행 출력 결과에서 볼 수 있는 것은 전체 스크립트를 실행하는 데 7초가 걸리고 new_lists 목록의 요소가 형식화되고 _new로 추가되었음을 알 수 있습니다. code>; 그뿐만 아니라 <code>random 모듈 선택 기능의 이유는 new_lists의 내용 순서가 old_lists의 내용 순서와 다르기 때문입니다. ; 실행될 때마다 순서가 달라지므로 old_lists > 순서는 보장되지 않습니다. 🎜


멀티스레딩 데모 사례

🎜코드 예시는 다음과 같습니다. 🎜rrreee🎜실행 결과는 다음과 같습니다. 🎜

Python 스레드의 생성 및 일반적인 방법(자세한 예)🎜🎜실행 결과에서 , 초기 주문 스레드 작업은 7초가 걸렸습니다. 멀티스레딩을 사용한 후 완료하는 데 1초밖에 걸리지 않아 작업 효율성이 크게 향상되었습니다. 🎜


스레드 문제

🎜위의 연습을 통해 우리는 스레드의 사용이 프로세스의 사용과 거의 동일하다는 것을 발견했습니다. 이들은 모두 서로 간섭하지 않고 프로그램을 실행할 수 있으며, 메인 스레드 프로그램이 하위 스레드의 작업을 실행하기 전에 완료되기를 기다리는 것을 방지할 수도 있습니다. 방금 데모 사례에서는 join() 함수를 사용하여 차단했습니다. 여기에서 join()을 제거하면 실행 효과를 볼 수 있습니다. 🎜🎜프로세스와 마찬가지로 스레드에도 특정 문제가 있습니다. 🎜🎜🎜스레드에 의해 실행되는 함수도 반환 값을 얻을 수 없습니다. 🎜🎜여러 스레드가 동시에 파일을 수정하면 수정된 파일에 데이터 혼란이 발생할 수도 있습니다(모두 동시에 파일을 실행하기 때문에, 특히 트랜잭션 시나리오를 처리할 때 특별한 주의가 필요합니다). 🎜🎜이 스레드에 존재하는 문제도 해결할 수 있습니다. 스레드 풀 및 전역 잠금의 다음 장에서 자세히 소개하겠습니다. 🎜🎜추천 학습: 🎜python 비디오 튜토리얼🎜🎜

위 내용은 Python 스레드의 생성 및 일반적인 방법(자세한 예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제