python线程怎么销毁

Python021

python线程怎么销毁,第1张

可以新建一个线程作为父线程,然后实际工作是在它的一个子线程里面做,父线程循环检测一个变量来决定是否退出。Talk is cheap

import threading

class TestThread(threading.Thread):

def __init__(self, thread_num=0, timeout=1.0):

super(TestThread, self).__init__()

self.thread_num = thread_num

self.stopped = False

self.timeout = timeout

def run(self):

def target_func():

inp = raw_input("Thread %d: " % self.thread_num)

print('Thread %s input %s' % (self.thread_num, inp))

subthread = threading.Thread(target=target_func, args=())

subthread.setDaemon(True)

subthread.start()

while not self.stopped:

subthread.join(self.timeout)

print('Thread stopped')

def stop(self):

self.stopped = True

def isStopped(self):

return self.stopped

thread = TestThread()

thread.start()

import time

print('Main thread Wainting')

time.sleep(2)

thread.stop()

thread.join()

【Python】线程的创建、执行、互斥、同步、销毁

还是《【Java】利用synchronized(this)完成线程的临界区》(点击打开链接)、《【Linux】线程互斥》(点击打开链接)、《【C++】Windows线程的创建、执行、互斥、同步、销毁》(点击打开链接)中的设置多个线程对一个ticket进行自减操作,用来说明Python中多线程的运用,涉及的创建、执行、互斥、同步、销毁问题。

运行结果如下,还是差不多,运行三次,每次的运行结果,每个线程最终的得票结果是不同的,但是4个线程最终“得票”的总和为 ticket 最初设置的值为100000,证明这4个线程成功实现了互斥。

虽然每次运行结果是不同,但是可以看得出每次运行结果大抵上是平均的。貌似Python对线程作系统资源的处理,比Java要好。

然而,Python总要实现多线程,代码并不像想象中简单,具体如下:

[python] view plain copy print?在CODE上查看代码片派生到我的代码片

# -*-coding:utf-8-*-

import threading

mutex_lock = threading.RLock() # 互斥锁的声明

ticket = 100000 # 总票数

# 用于统计各个线程的得票数

ticket_for_thread1 = 0

ticket_for_thread2 = 0

ticket_for_thread3 = 0

ticket_for_thread4 = 0

class myThread(threading.Thread): # 线程处理函数

def __init__(self, name):

threading.Thread.__init__(self) # 线程类必须的初始化

self.thread_name = name # 将传递过来的name构造到类中的name

def run(self):

# 声明在类中使用全局变量

global mutex_lock

global ticket

global ticket_for_thread1

global ticket_for_thread2

global ticket_for_thread3

global ticket_for_thread4

while 1:

mutex_lock.acquire() # 临界区开始,互斥的开始

# 仅能有一个线程↓↓↓↓↓↓↓↓↓↓↓↓

if ticket >0:

ticket -= 1

# 统计哪到线程拿到票

print "%s抢到了票!票还剩余:%d。" % (self.thread_name, ticket)

if self.thread_name == "线程1":

ticket_for_thread1 += 1

elif self.thread_name == "线程2":

ticket_for_thread2 += 1

elif self.thread_name == "线程3":

ticket_for_thread3 += 1

elif self.thread_name == "线程4":

ticket_for_thread4 += 1

else:

break

# 仅能有一个线程↑↑↑↑↑↑↑↑↑↑↑↑

mutex_lock.release() # 临界区结束,互斥的结束

mutex_lock.release() # python在线程死亡的时候,不会清理已存在在线程函数的互斥锁,必须程序猿自己主动清理

print "%s被销毁了!" % (self.thread_name)

# 初始化线程

thread1 = myThread("线程1")

thread2 = myThread("线程2")

thread3 = myThread("线程3")

thread4 = myThread("线程4")

# 开启线程

thread1.start()

thread2.start()

thread3.start()

thread4.start()

# 等到线程1、2、3、4结束才进行以下的代码(同步)

thread1.join()

thread2.join()

thread3.join()

thread4.join()

print "票都抢光了,大家都散了吧!"

print "=========得票统计========="

print "线程1:%d张" % (ticket_for_thread1)

print "线程2:%d张" % (ticket_for_thread2)

print "线程3:%d张" % (ticket_for_thread3)

print "线程4:%d张" % (ticket_for_thread4)

1、从上面的代码可以看出,在Python2.7中要使用线程必须使用threading而不是古老的thread模块。

如果你像网上部分遗留依旧的文章一样,在Python2.7中使用thread来实现线程,至少在Eclipse的Pydev中会报错:sys.excepthook is missing,lost sys.stderr如下图所示:

所以必须使用现时Python建议使用的threading。

2、与其它编程语言类似,声明一个互斥锁,与一系列的得票数。之后,与Java同样地,Python实现线程的函数,是要重写一个类。而类中使用全局变量,则与同为脚本语言的PHP一样《【php】global的使用与php的全局变量》(点击打开链接),要用global才能使用这个全局变量,而不是C/C++可以直接使用。

3、需要注意的,Python需要在线程跑完class myThread(threading.Thread)这个类的def run(self)方法之前,必须自己手动清理互斥锁,它不会像其它编程语言那样,说线程跑完def run(self)方法,会自然而然地清理该线程被创建的互斥锁。如果没有最后一句手动清理互斥锁,则会造成死锁。

4、最后与其它编程语言一样了,利用线程的join方法可以等待这个线程跑完def run(self)方法中的所有代码,才执行之后的代码,实现同步。否则主函数中的代码,相当于与父线程。主函数开启的线程,相当于其子线程,互不影响的。

Python线程

进程有很多优点,它提供了多道编程,可以提高计算机CPU的利用率。既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的。

主要体现在一下几个方面:

进程只能在一个时间做一个任务,如果想同时做两个任务或多个任务,就必须开启多个进程去完成多个任务。

进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。

每个进程都有自己的独立空间,所以多进程的创建,销毁相比于多线程更加耗时,也更加占用系统资源。

进程是资源分配的最小单位,线程是CPU调度的最小单位,每一个进程中至少有一个线程。 

线程与进程的区别

可以归纳为以下4点:

1)地址空间:进程间相互独立的每个进程都有自己独立的内存空间,也就是说一个进程内的数据在另一个进程是不可见的。但同一进程中的各线程间数据是共享的。

2)通信:由于每个进程有自己独立的内存空间,所以进程间通信需要IPC,而进程内的数据对于多个线程来说是共享的,每个线程都可以访问,所以为了保证数据的一致性,需要使用锁。

3)调度和切换:线程上下文切换比进程上下文切换要快得多。

4)在多线程操作系统中,进程不是一个可执行的实体,它主要的功能是向操作系统申请一块内存空间,然后在内存空间中开线程来执行任务,相当于一个容器,容器中的线程才是真正的执行体。一个进程可以包含多个线程,而一个线程是不能包含进程的。因为进程是系统分配资源的最小单位,所以线程不能向操作系统申请自己的空间,但一个线程内可以包含多个线程。

相关推荐:《Python视频教程》

线程的特点:

在多线程的操作系统中,通常是在一个进程中包括多个线程,每个线程都是作为利用CPU的基本单位,是花费最小开销的实体。线程具有以下属性。

1)轻型实体

线程中的实体基本上不拥有系统资源,只是有一点必不可少的、能保证独立运行的资源。

线程的实体包括程序、数据和TCB。线程是动态概念,它的动态特性由线程控制块TCB(Thread Control Block)描述。

2)独立调度和分派的基本单位。

在多线程OS中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很“轻”,故线程的切换非常迅速且开销小(在同一进程中的)。

3)共享进程资源。

在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的进程id,这意味着,线程可以访问该进程的每一个内存资源;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。由于同一个进程内的线程共享内存和文件,所以线程之间互相通信不必调用内核

4)可并发执行

在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行;同样,不同进程中的线程也能并发执行,充分利用和发挥了处理机与外围设备并行工作的能力。

线程的实现可以分为两类:

用户级线程(User-Level Thread)和内核级线程(Kernel-Level Thread),后者又称为内核支持的线程或轻量级进程。在多线程操作系统中,各个系统的实现方式并不相同,在有的系统中实现了用户级线程,有的系统中实现了内核级线程。

用户线程和内核线程的区别:

1、内核支持线程是OS内核可感知的,而用户级线程是OS内核不可感知的。

2、用户级线程的创建、撤消和调度不需要OS内核的支持,是在语言(如Java)这一级处理的;而内核支持线程的创建、撤消和调度都需OS内核提供支持,而且与进程的创建、撤消和调度大体是相同的。

3、用户级线程执行系统调用指令时将导致其所属进程被中断,而内核支持线程执行系统调用指令时,只导致该线程被中断。

4、在只有用户级线程的系统内,CPU调度还是以进程为单位,处于运行状态的进程中的多个线程,由用户程序控制线程的轮换运行;在有内核支持线程的系统内,CPU调度则以线程为单位,由OS的线程调度程序负责线程的调度。

5、用户级线程的程序实体是运行在用户态下的程序,而内核支持线程的程序实体则是可以运行在任何状态下的程序。

内核线程的优缺点:

优点:当有多个处理机时,一个进程的多个线程可以同时执行。

缺点:由内核进行调度。

用户线程的优缺点:

优点:

线程的调度不需要内核直接参与,控制简单。

可以在不支持线程的操作系统中实现。

创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多。

允许每个进程定制自己的调度算法,线程管理比较灵活。

线程能够利用的表空间和堆栈空间比内核级线程多。

同一进程中只能同时有一个线程在运行,如果有一个线程使用了系统调用而阻塞,那么整个进程都会被挂起。另外,页面失效也会产生同样的问题。

缺点:

资源调度按照进程进行,多个处理机下,同一个进程中的线程只能在同一个处理机下分时复用。