为什么苏州网络进不了网站,西安网站建设工程,智能建站,网站建设费用多少钱一、进程和线程进程#xff1a;是程序的一次执行#xff0c;每个进程都有自己的地址空间、内存、数据栈及其他记录运行轨迹的辅助数据。线程#xff1a;所有的线程都运行在同一个进程当中#xff0c;共享相同的运行环境。线程有开始、顺序执行和结束三个部分#xff0c; …一、进程和线程进程是程序的一次执行每个进程都有自己的地址空间、内存、数据栈及其他记录运行轨迹的辅助数据。线程所有的线程都运行在同一个进程当中共享相同的运行环境。线程有开始、顺序执行和结束三个部分 线程是操作系统能够进行运算调度的最小单位它被包含在进程之中是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流一个进程中可以并发多个线程每条线程并行执行不同的任务。二、多线程多线程类似于同时执行多个不同程序多线程运行有如下优点使用线程可以把占据长时间的程序中的任务放到后台去处理。用户界面可以更加吸引人比如用户点击了一个按钮去触发某些事件的处理可以弹出一个进度条来显示处理的进度。程序的运行速度可能加快。在一些等待的任务实现上如用户输入、文件读写和网络收发数据等线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行必须依存在应用程序中由应用程序提供多个线程执行控制。每个线程都有他自己的一组 CPU 寄存器称为线程的上下文该上下文反映了线程上次运行该线程的 CPU 寄存器的状态。指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器线程总是在进程得到上下文中运行的这些地址都用于标志拥有线程的进程地址空间中的内存。线程可以被抢占中断。在其他线程正在运行时线程可以暂时搁置也称为睡眠 -- 这就是线程的退让。线程可以分为:内核线程由操作系统内核创建和撤销。用户线程不需要内核支持而在用户程序中实现的线程。三、Python线程在Python3中实现的大部分运行任务里不同的线程实际上并没有同时运行它们只是看起来像是同时运行的。同时执行多个任务需要使用非标准的Python运行方式用不同的语言编写一部分代码或者使用多进程模块multiprocessing但这么做会带来一些额外的开销。由于Python默认的运行环境是CPythonC语言开发的Python)所以线程化可能不会提升所有任务的运行速度。这是因为和GILGlobal Interpreter Lock的交互形成了限制一次只能运行一个Python线程。线程化的一般替代方法是让各项任务花费大量时间等待外部事件。但问题是如果想缩短等待时间会需要大量的CPU计算结果是程序的运行速度可能并不会提升。如果只用Python语言在默认的Python执行环境下运行并且遇到CPU受限的问题那就应该用多进程模块multiprocessing来解决。Python3 线程中常用的两个模块为_threadthreading(推荐使用)thread 模块已被废弃用户可以使用 threading 模块代替。所以在 Python3 中不能再使用thread 模块。为了兼容性Python3 将 thread 重命名为 _thread。_thread是低级模块threading是高级模块对_thread进行了封装。绝大多数情况下我们只需要使用threading这个高级模块。Python中使用线程有两种方式函数或者用类来包装线程对象。函数式调用 _thread 模块中的start_new_thread()函数来产生新线程。它将产生一个新线程在新的线程中用指定的参数和可选的kwargs来调用这个函数。语法如下:_thread.start_new_thread ( function, args[, kwargs] )参数说明:function - 线程函数。args - 传递给线程函数的参数,他必须是个tuple类型。kwargs - 可选参数。注意使用这个方法时一定要加time.sleep()函数否则每个线程都可能不执行。此方法还有一个缺点遇到较复杂的问题时线程数不易控制。# codingutf-8import _thread
import time# 为线程定义一个函数
def print_time(threadName, delay):count 0while count 5:time.sleep(delay)count 1print(%s: %s % (threadName, time.ctime(time.time())))# 创建两个线程
try:_thread.start_new_thread(print_time, (Thread-1, 2,))_thread.start_new_thread(print_time, (Thread-2, 4,))
except:print(Error: 无法启动线程)while 1:pass
运行结果Thread-1: Fri Mar 3 22:46:01 2023
Thread-2: Fri Mar 3 22:46:03 2023
Thread-1: Fri Mar 3 22:46:03 2023
Thread-1: Fri Mar 3 22:46:06 2023
Thread-2: Fri Mar 3 22:46:07 2023
Thread-1: Fri Mar 3 22:46:08 2023
Thread-1: Fri Mar 3 22:46:10 2023
Thread-2: Fri Mar 3 22:46:11 2023
Thread-2: Fri Mar 3 22:46:16 2023
Thread-2: Fri Mar 3 22:46:20 2023执行以上程后可以按下 ctrl-c 退出。四、线程模块Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。_thread 提供了低级别的、原始的线程以及一个简单的锁它相比于 threading 模块的功能还是比较有限的。threading 模块除了包含 _thread 模块中的所有方法外还提供的其他方法threading.currentThread(): 返回当前的线程变量。threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前不包括启动前和终止后的线程。threading.activeCount(): 返回正在运行的线程数量与len(threading.enumerate())有相同的结果。除了使用方法外线程模块同样提供了Thread类来处理线程Thread类提供了以下方法:run(): 用以表示线程活动的方法。start():启动线程活动。join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。isAlive(): 返回线程是否活动的。getName(): 返回线程名。setName(): 设置线程名。使用 threading 模块创建线程有两种方法来创建多线程1、继承Thread类并重写它的run()方法2、是实例化threading.Thread对象时将线程要执行的任务函数作为参数传入线程。我们通过从 threading.Thread 继承创建一个新的子类并实例化后调用 start() 方法启动新线程# codingutf-8import threading
import timeexitFlag 0class myThread(threading.Thread):def __init__(self, threadID, name, delay):threading.Thread.__init__(self)self.threadID threadIDself.name nameself.delay delaydef run(self):print(开始线程 self.name)print_time(self.name, self.delay, 5)print(退出线程 self.name)def print_time(threadName, delay, counter):while counter:if exitFlag:threadName.exit()time.sleep(delay)print(%s: %s % (threadName, time.ctime(time.time())))counter - 1# 创建新线程
thread1 myThread(1, Thread-1, 1)
thread2 myThread(2, Thread-2, 2)# 开启新线程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(退出主线程)
运行结果五、线程同步如果多个线程共同对某个数据修改则可能出现不可预料的结果为了保证数据的正确性需要对多个线程进行同步。使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步这两个对象都有 acquire 方法和 release 方法对于那些需要每次只允许一个线程操作的数据可以将其操作放到 acquire 和 release 方法之间。# codingutf-8import threading
import timeclass MyThread(threading.Thread):def __init__(self, name, threadID, counter):threading.Thread.__init__(self)self.name nameself.threadID threadIDself.counter counterdef run(self): # 定义每个线程要运行的函数print(开启线程 self.name)# 获取锁用于线程同步threadLock.acquire()print_time(self.name, self.counter, 5)# print(name:%s % self.name)# 释放锁开启下一个线程threadLock.release()time.sleep(2)def print_time(threadName, delay, counter):while counter:time.sleep(delay)print(%s: %s % (threadName, time.ctime(time.time())))counter - 1threadLock threading.Lock()
threads []if __name__ __main__:# 创建新线程t1 MyThread(小心愿, 1, 1)t2 MyThread(超级飞侠, 2, 2)# 开启新线程t1.start()t2.start()# 添加线程到线程列表threads.append(t1)threads.append(t2)# 等待所有线程完成for t in threads:t.join()print(退出主线程)
运行结果开启线程 小心愿
开启线程 超级飞侠
小心愿: Fri Mar 3 22:58:28 2023
小心愿: Fri Mar 3 22:58:29 2023
小心愿: Fri Mar 3 22:58:30 2023
小心愿: Fri Mar 3 22:58:31 2023
小心愿: Fri Mar 3 22:58:32 2023
超级飞侠: Fri Mar 3 22:58:34 2023
超级飞侠: Fri Mar 3 22:58:36 2023
超级飞侠: Fri Mar 3 22:58:38 2023
超级飞侠: Fri Mar 3 22:58:40 2023
超级飞侠: Fri Mar 3 22:58:42 2023
退出主线程六、线程优先级队列 QueuePython 的 Queue 模块中提供了同步的、线程安全的队列类包括FIFO先入先出)队列QueueLIFO后入先出队列LifoQueue和优先级队列 PriorityQueue。这些队列都实现了锁原语能够在多线程中直接使用可以使用队列来实现线程间的同步。Queue 模块中的常用方法:Queue.qsize() 返回队列的大小Queue.empty() 如果队列为空返回True,反之FalseQueue.full() 如果队列满了返回True,反之FalseQueue.full 与 maxsize 大小对应Queue.get([block[, timeout]])获取队列timeout等待时间Queue.get_nowait() 相当Queue.get(False)Queue.put(item) 写入队列timeout等待时间Queue.put_nowait(item) 相当Queue.put(item, False)Queue.task_done() 在完成一项工作之后Queue.task_done()函数向任务已经完成的队列发送一个信号Queue.join() 实际上意味着等到队列为空再执行别的操作# codingutf-8import queue
import threading
import timeexitFlag 0class myThread(threading.Thread):def __init__(self, threadID, name, q):threading.Thread.__init__(self)self.threadID threadIDself.name nameself.q qdef run(self):print(开启线程 self.name)process_data(self.name, self.q)print(退出线程 self.name)def process_data(threadName, q):while not exitFlag:queueLock.acquire()if not workQueue.empty():data q.get()queueLock.release()print(%s processing %s % (threadName, data))else:queueLock.release()time.sleep(1)threadList [Thread-1, Thread-2, Thread-3]
nameList [One, Two, Three, Four, Five]
queueLock threading.Lock()
workQueue queue.Queue(10)
print(workQueue)
print(type(workQueue))threads []
threadID 1# 创建新线程
for tName in threadList:thread myThread(threadID, tName, workQueue)thread.start()threads.append(thread)threadID 1# 填充队列
queueLock.acquire()
for word in nameList:workQueue.put(word)
queueLock.release()print(workQueue.queue) # 查看队列中所有元素
print(workQueue.qsize()) # 返回队列的大小# 等待队列清空
# Queue.get(blockTrue, timeoutNone)读出队列的一个元素阻塞调用无等待时间
while not workQueue.empty():pass# 通知线程是时候退出
exitFlag 1# 等待所有线程完成
for t in threads:t.join()
print(退出主线程)
运行结果queue.Queue object at 0x000001629C510D30
class queue.Queue
开启线程Thread-1
开启线程Thread-2
开启线程Thread-3deque([One, Two, Three, Four, Five])
5Thread-3 processing One
Thread-1 processing TwoThread-2 processing ThreeThread-3 processing Four
Thread-2 processing Five
退出线程Thread-2退出线程Thread-3退出线程Thread-1