进程,线程

线程(thread)

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的就是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并执行不同的任务。

threading

用于提供线程相关的操作。

#!/usr/bin/env python3

import threading
import time

def show(arg):
    time.sleep(1)
    print(‘thread‘+str(arg))

for i in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print(‘main thread stop‘)

上述代码创建了10个前台线程,然后控制器交给了CPU,CPU根据指定算法进行调度,分片执行指令

其他方法:

  • start               线程准备就绪,等待CPU调度
  • setName        为线程设置名称
  • getName        获取线程名称
  • setDaemon    设置为后台线程或前台线程(默认)
        • 如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
        • 如果是前台线程,主线程执行过程中,前台线程也进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
  • join            逐个执行每个线程,执行完毕后继续往下执行,该方法使的多线程变得无意义
  • run            线程被CPU调度后执行Thread类对象的run方法

 

调用的方法:

直接调用

import threading
import time

def sayhi(num):    # 定义每个线程要运行的函数
    print("running on number:%s" %num)
    time.sleep(3)

if __name__ == "__main__":
    t_list = []
    for i in range(10):
        t = threading.Thread(target=sayhi,args=[i,])
        t.start()
        t_list.append(t)
    for i in t_list:
        i.join()        # 阻断,等上面都执行完成后再执行后面的程序

    print("---main---")

 

继承调用:

import threading
import time

class MyThread(threading.Thread):
    def __init__(self,num):
        threading.Thread.__init__(self)
        self.num = num

    def run(self):#定义每个线程要运行的函数

        print("running on number:%s" %self.num)

        time.sleep(3)

if __name__ == ‘__main__‘:

    t1 = MyThread(1)
    t2 = MyThread(2)
    t1.start()
    t2.start()

 

线程锁(互斥锁Mutex)

一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,这样就会出现2个线程同时要修改同一份数据。(3.x版本中不会出现这种情况)

未加锁的版本:

import time
import threading

def addNum():
    global num #在每个线程中都获取这个全局变量
    print(‘--get num:‘,num )
    time.sleep(1)
    num  -=1 #对此公共变量进行-1操作

num = 100  #设定一个共享变量
thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list: #等待所有线程执行完毕
    t.join()

print(‘final num:‘, num )

加锁版本:

import time
import threading

def addNum():
    global num #在每个线程中都获取这个全局变量
    print(‘--get num:‘,num )
    time.sleep(1)
    lock.acquire() #修改数据前加锁
    num  -=1 #对此公共变量进行-1操作
    lock.release() #修改后释放

num = 100  #设定一个共享变量
thread_list = []
lock = threading.Lock() #生成全局锁
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list: #等待所有线程执行完毕
    t.join()

print(‘final num:‘, num )

 

RLock(递归锁)

就是会有多层锁。

#!/usr/bin/env python3
import threading

def run1():
    print("grab the first part data")
    lock.acquire()
    global num
    num +=1
    lock.release()
    return num
def run2():
    print("grab the second part data")
    lock.acquire()
    global  num2
    num2+=1
    lock.release()
    return num2
def run3():
    lock.acquire()
    res = run1()
    print(‘--------between run1 and run2-----‘)
    res2 = run2()
    lock.release()
    print(res,res2)

if __name__ == ‘__main__‘:

    num,num2 = 0,0
    lock = threading.RLock()        #$ Rlock递归锁
    for i in range(10):
        t = threading.Thread(target=run3)
        t.start()

while threading.active_count() != 1:
    print(threading.active_count())
else:
    print(‘----all threads done---‘)
    print(num,num2)

 

Semaphore(信号量)

互斥锁同时只允许一个线程更改数据,而Semaphore是同时允许一定量的线程更改数据,比如去理发店,有3个理发师,最多允许3个人理发,后面的人只能排队等待。

import threading
import time

def run(n):
    semaphore.acquire()
    time.sleep(1)
    print("run the thread: %s\n" %n)
    semaphore.release()

if __name__ == ‘__main__‘:

    num= 0
    semaphore  = threading.BoundedSemaphore(5) #最多允许5个线程同时运行
    for i in range(20):
        t = threading.Thread(target=run,args=(i,))
        t.start()

while threading.active_count() != 1:
    pass #print threading.active_count()
else:
    print(‘----all threads done---‘)
    print(num)

 

Events

python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set , wait , clear

事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为False ,那么程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么 event.wait 方法便不阻塞

  • clear:将“Flag”设置为False
  • set:将“Flag”设置为True

通过event来实现两个或多个线程间的交互,下面是一个红绿灯的例子。

import threading
import time
import random
def light():
    if not event.isSet():
        event.set() #wait就不阻塞 #绿灯状态
    count = 0
    while True:
        if count < 10:
            print(‘\033[42;1m--green light on---\033[0m‘)
        elif count <13:
            print(‘\033[43;1m--yellow light on---\033[0m‘)
        elif count <20:
            if event.isSet():
                event.clear()
            print(‘\033[41;1m--red light on---\033[0m‘)
        else:
            count = 0
            event.set() #打开绿灯
        time.sleep(1)
        count +=1

def car(n): #no bug version
    while 1:
        time.sleep(1)
        if  event.isSet(): #绿灯
            print("car [%s] is running.." % n)
        else:
            print("car [%s] is waiting for the red light.." %n)
            event.wait()

def car2(n):
    while 1:
        time.sleep(random.randrange(10))
        if  event.isSet(): #绿灯
            print("car [%s] is running.." % n)
        else:
            print("car [%s] is waiting for the red light.." %n)

if __name__ == ‘__main__‘:
    event = threading.Event()
    Light = threading.Thread(target=light)
    Light.start()
    for i in range(3):
        t = threading.Thread(target=car,args=(i,))
        t.start()

 

生产着消费着模型

主要是基于单向队列queue,单向队列的遵循的是先进先出的原则

下面模拟一个吃包子的场景

import time,random
import queue,threading
q = queue.Queue()
def Producer(name):
  count = 0
  while count <20:
    time.sleep(random.randrange(3))
    q.put(count)
    print(‘Producer %s has produced %s baozi..‘ %(name, count))
    count +=1
def Consumer(name):
  count = 0
  while count <20:
    time.sleep(random.randrange(4))
    if not q.empty():
        data = q.get()
        print(data)
        print(‘\033[32;1mConsumer %s has eat %s baozi...\033[0m‘ %(name, data))
    else:
        print("-----no baozi anymore----")
    count +=1
p1 = threading.Thread(target=Producer, args=(‘A‘,))
c1 = threading.Thread(target=Consumer, args=(‘B‘,))
p1.start()
c1.start()

 

进程

多进程multiproceessing

from multiprocessing import Process
import os

def info(title):
    print(title)
    print(‘module name:‘, __name__)
    print(‘parent process:‘, os.getppid())    #$ 父进程ID
    print(‘process id:‘, os.getpid())    #$ 进程ID
    print("\n\n")

def f(name):
    info(‘\033[31;1mfunction f\033[0m‘)
    print(‘hello‘, name)

if __name__ == ‘__main__‘:
    info(‘\033[32;1mmain process line\033[0m‘)
    p = Process(target=f, args=(‘bob‘,))
    p.start()
    p.join()

 

进程间通讯

不同进程间内存是不共享的,可以使用以下方法进行进程间的数据交换

Queues

使用方法和threading里的queue差不多

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, ‘hello‘])

if __name__ == ‘__main__‘:
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, ‘hello‘]"
    p.join()

 

Pipes

管道,双向的

from multiprocessing import Process, Pipe

def f(conn):
    conn.send([42, None, ‘hello‘])
    conn.close()

if __name__ == ‘__main__‘:
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print(parent_conn.recv())   # prints "[42, None, ‘hello‘]"
    p.join()

 

Managers

from multiprocessing import Process, Manager

def f(d, l,n):
    d[n] =n
    d[‘2‘] = 2
    d[0.25] = None
    l.append(n)
    print(l)

if __name__ == ‘__main__‘:
    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(5))
        p_list = []
        for i in range(10):
            p = Process(target=f, args=(d, l,i))
            p.start()
            p_list.append(p)
        for res in p_list:
            res.join()
        print(d)
        print(l)

 

进程同步

from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    try:
        print(‘hello world‘, i)
    finally:
        l.release()

if __name__ == ‘__main__‘:
    lock = Lock()

    for num in range(10):
        Process(target=f, args=(lock, num)).start()

 

进程池

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进程,那么程序就会等待,直到进程池中有可用进程为止。

进程池中有两个方法:

  • apply
  • apply_async
from  multiprocessing import Process,Pool
import time

def Foo(i):
    time.sleep(2)
    return i+100

def Bar(arg):
    print(‘-->exec done:‘,arg)

pool = Pool(5)

for i in range(10):
    pool.apply_async(func=Foo, args=(i,),callback=Bar)    #$ 异步
    #pool.apply(func=Foo, args=(i,))

print(‘end‘)
pool.close()
pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
时间: 2024-08-27 15:04:53

进程,线程的相关文章

Linux下进程线程,Nignx与php-fpm的进程线程方式

1.进程与线程区别 进程是程序执行时的一个实例,即它是程序已经执行到课中程度的数据结构的汇集.从内核的观点看,进程的目的就是担当分配系统资源(CPU时间.内存等)的基本单位. 线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.一个进程由几个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),线程与同属一个进程的其他的线程共享进程所拥有的全部资源. "进程——资源分配的最小单位,线程——程序执行的最小单位" 进程有独立的地

android 进程/线程管理(四)续----消息机制的思考(自定义消息机制)

继续分析handler 和looper 先看看handler的 public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } } 所以消息的处理分层三种,就是 1.传入一

进程/线程介绍

一.进程 进程可以认为是程序执行时的一个实例.进程是系统进行资源分配的独立的实体,且每个进程拥有独立 的地址空间.一个进程无法直接访问另一个进程的变量和数据结构,如果希望让一个进程访问另一个进程 的资源,需要使用进程间通信,比如:管道,有名管道,信号,信号量,消息队列,套接字等. 一个进程可以拥有多个线程,每个线程使用其所属进程的栈空间.线程和进程的一个主要区别是,同一程序内 的多个线程会共享部分状态,多个线程可以读写同一块内存(一个进程无法直接访问另一进程的内存).同时 每个线程还拥有自己的寄

进程线程协程那些事儿

一.进程与线程 1.进程 我们电脑的应用程序,都是进程,假设我们用的电脑是单核的,cpu同时只能执行一个进程.当程序出于I/O阻塞的时候,CPU如果和程序一起等待,那就太浪费了,cpu会去执行其他的程序,此时就涉及到切换,切换前要保存上一个程序运行的状态,才能恢复,所以就需要有个东西来记录这个东西,就可以引出进程的概念了. 进程就是一个程序在一个数据集上的一次动态执行过程.进程由程序,数据集,进程控制块三部分组成.程序用来描述进程哪些功能以及如何完成:数据集是程序执行过程中所使用的资源:进程控制

9 异常处理 操作系统 进程线程 队列+生产消费者模型 进程同步 回调函数

异常处理 异常就是程序运行时发生错误的信号,在python中,错误触发的异常如下 异常的种类: AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x IOError 输入/输出异常:基本上是无法打开文件 ImportError 无法引入模块或包:基本上是路径问题或名称错误 IndentationError 语法错误(的子类) :代码没有正确对齐 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5] KeyError 试图访

操作系统:进程/线程同步的方式和机制,进程间通信

一.进程/线程间同步机制. 临界区.互斥区.事件.信号量四种方式临界区(Critical Section).互斥量(Mutex).信号量(Semaphore).事件(Event)的区别1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问.在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占.2.互斥量:采用互斥对象机

进程/线程

进程/线程控制: 创建                  退出                      等待 多进程               fork()         exit()           wait() 多线程      pthread_create    pthread_exit()        pthread_join() 线程的同步与互斥: 线程的互斥:  互斥锁 初始化互斥锁 int pthread_mutex_init(pthread_mutex_t *mute

java 进程/线程

进程 OS并发的一个任务 CPU分时间片交替执行 宏观并行 微观串行 线程:在一个进程中并发的一个顺序执行流程 线程的组成: 1.数据 堆空间共享 栈空间独立 2.CPU 3.代码 Thread 线程对象 继承Thread类型 覆盖run方法 直接创建Thread对象 实现Runnable接口 实现run方法 先创建Runnable对象,再创建Thread对象 多线程共同访问同一个对象(临界资源),如果破坏了不可分割的操作(原子操作),就会发生数据不一致的情况 synchronized 同步 s

python基础-------进程线程(二)

Python中的进程线程(二) 一.python中的"锁" 1.GIL锁(全局解释锁) 含义: Python中的线程是操作系统的原生线程,Python虚拟机使用一个全局解释器锁(Global Interpreter Lock)来互斥线程对Python虚拟机的使用.为了支持多线程机制,一个基本的要求就是需要实现不同线程对共享资源访问的互斥,所以引入了GIL.GIL:在一个线程拥有了解释器的访问权之后,其他的所有线程都必须等待它释放解释器的访问权,即使这些线程的下一条指令并不会互相影响.在

进程/线程同步的方式和机制,进程间通信

转自: http://www.cnblogs.com/memewry/archive/2012/08/22/2651696.html 一.进程/线程间同步机制. 临界区.互斥区.事件.信号量四种方式临界区(Critical Section).互斥量(Mutex).信号量(Semaphore).事件(Event)的区别1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问.在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后