首页 > 编程语言 > 详细

进程和线程

时间:2020-05-24 14:44:16      阅读:62      评论:0      收藏:0      [点我收藏+]

进程

广义定义:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。

狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。

在操作系统中引入进程的概念,是为了实现多个程序的并发执行。

进程的状态

技术分享图片

进程的创建

Linux操作系统:

import os
print(Process (%s) start... % os.getpid())
# Only works on Unix/Linux/Mac:
pid = os.fork() #创建一个子进程
if pid == 0:
    print(I am child process (%s) and my parent is %s. % (os.getpid(), 
os.getppid()))
else:
    print(I (%s) just created a child process (%s). % (os.getpid(), pid))
import os
import time

cnt = 100

print(Process (%s) (%s) start... % (os.getpid(), os.getppid()))
# Only works on Unix/Linux/Mac:
pid = os.fork() #创建一个子进程
if pid == 0:
    time.sleep(3)
    print(cnt, I am child process (%s) and my parent is %s. % (os.getpid(),os.getppid()))
else:
    cnt = 1000
    print(cnt, I (%s) just created a child process (%s). % (os.getpid(), pid))

    #os.wait()
    while True:
        pass

fork() 调用一次返回两次

在父进程中返回大于0的值pid,pid:子进程的pid(进程id)

在子进程中返回0

os.getpid(): 获取当前进程的pid

os.getppid(): 获取父进程的pid

windows操作系统:

from multiprocessing import Process
import os
# 子进程要执行的代码
def run_proc(name):
    print(Run child process %s (%s)... % (name, os.getpid()))
if __name__==__main__:
print(Parent process %s. % os.getpid())
p = Process(target=run_proc, args=(test,))
print(Child process will start.)
p.start()
p.join()
print(Child process end.)

进程函数传参

import os
import time

# 子进程要执行的代码
def run_proc(*args):
    print(args[0], args[1])

if __name__==__main__:
    p = Process(target=run_proc, args=(test1,"test2"))
    p.start()
    p.join() #阻塞等待子进程退出,并且回收子进程的资源
    print(Child process end.)

进程池

from multiprocessing import Pool
import os, time, random

def worker(msg):
    t_start = time.time()
    print("%s开始执行,进程号为%d" % (msg,os.getpid()))
    # random.random()随机生成0~1之间的浮点数
    time.sleep(random.random()*2)
    t_stop = time.time()
    print(msg,"执行完毕,耗时%0.2f" % (t_stop-t_start))

if __name__ == "__main__":
    po = Pool(5)  # 定义一个进程池,最大进程数5
    for i in range(0,10):
        po.apply_async(worker,(i,))  # Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))

    for i in range(100,110):
        po.apply_async(worker,(i,))  # Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))

    print("----start----")
    po.close()  # 关闭进程池,关闭后po不再接收新的请求
    po.join()  # 等待po中所有子进程执行完成,再执行下面的代码,可以设置超时时间join(timeout=)
    print("-----end-----")

孤儿进程和僵尸进程

子进程是父进程的拷贝。

父子进程拥有自己独立的地址空间。

孤儿进程:如果一个进程的父进程先于他自己退出,那么这个进程就叫做孤儿进程。

僵尸进程:Linux中一个进程‘退出‘以后其实并没有真正退出,而是系统将其状态标记为“zombie”状态,如果该进程的父进程没有回收子进程的系统资源,则该进程就叫僵尸进程。危害:浪费系统资源。

如何防止僵尸进程?

一般,为了防止产生僵尸进程,在fork子进程之后我们都要wait它们;同时,当子进程退出的时候,内核都会给父进程一个SIGCHLD信号,所以我们可以建立一个捕获SIGCHLD信号的信号处理函数,在函数体中调用wait(或waitpid),就可以清理退出的子进程以达到防止僵尸进程的目的。

线程

线程:进程内部的执行分支, 是系统进行任务调度的最小单元。

线程的查看:

ps -eLf

  PID        PPID     LWP C NLWP CMD

    进程ID   父进程ID

    LWP:light weight process 轻量级进程 => 线程

线程的创建

import time, threading

#线程函数
def loop():
    print(thread %s is running... % threading.current_thread().name)

#打印当前运行的线程的名称
print(thread %s is running... % threading.current_thread().name)
t = threading.Thread(target=loop, name=LoopThread)
t.start() #启动线程
t.join() #阻塞等待子线程退出
print(thread %s ended. % threading.current_thread().name)

线程数据的同步

互斥锁/互斥量 mutex

A、创建锁 mutex = threading.Lock()

B、加锁 mutex.acquire()

C、解锁 mutex.release()

import time, threading

cnt = 0

#构造一个互斥锁
mutex = threading.Lock()

#子线程 线程函数
def loop():
    global cnt
    #mutex.acquire()
    for i in range(1000000):
        #加锁
        mutex.acquire()
        cnt += 1
        #解锁
        mutex.release()
    #mutex.release()
    print(threading.current_thread().name, ": ", cnt)
    print(thread %s is running... % threading.current_thread().name)

#主线程
#打印当前运行的线程的名称
print(thread %s is running... % threading.current_thread().name)
t = threading.Thread(target=loop, name=LoopThread)
t.start() #启动线程

t1 = threading.Thread(target=loop, name=LoopThread1)
t1.start() #启动线程

t2 = threading.Thread(target=loop, name=LoopThread2)
t2.start() #启动线程

t.join() #阻塞等待子线程退出
t1.join() #阻塞等待子线程退出
t2.join()
print("MainThread: ", cnt)

print(thread %s ended. % threading.current_thread().name)

线程数据的访问

import time, threading

cnt = 100

#子线程 线程函数
def loop():
    global cnt
    cnt = 1000
    print(threading.current_thread().name, ": ", cnt)
    print(thread %s is running... % threading.current_thread().name)

def loop1():
    global cnt
    print(threading.current_thread().name, ": ", cnt)
    cnt = 2000
    print(threading.current_thread().name, ": ", cnt)
    print(thread %s is running... % threading.current_thread().name)

#主线程
#打印当前运行的线程的名称
print(thread %s is running... % threading.current_thread().name)
t = threading.Thread(target=loop, name=LoopThread)
t.start() #启动线程

t1 = threading.Thread(target=loop1, name=LoopThread1)
t1.start() #启动线程

t.join() #阻塞等待子线程退出
t1.join() #阻塞等待子线程退出
print("MainThread: ", cnt)

 

进程和线程

原文:https://www.cnblogs.com/-Leif/p/12950851.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!