例子简单了解线程与进程

目录

线程与进程概念

进程

线程

线程与进程状态

协程

总体

线程例

基本操作

全局变量操作

进程例


线程与进程概念

进程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动。是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中。

线程

线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流。

线程与进程状态

进程退出时该进程所产生的线程都会被强制退出并清除线程可与属于同一进程的其它线程共享进程所拥有的全部资源
但是其本身基本上不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器、一组寄存器和栈)。


多进程适合在CPU 密集型操作(cpu 操作指令比较多,如科学计算,位数多的浮点运算)
多线程适合在IO 密集型操作(读写数据操作较多的,比如爬虫)
线程是并发进程是并行进程之间相互独立,是系统分配资源的最小单位,同一个进程中的所有线程共享资源。

协程

协程是用户态的轻量级线程,调度有用户控制,拥有自己的寄存器上下文和栈,切换基本没有内核切换的开销,切换灵活。

总体

  1. 一个进程中可以并发多个线程,每条线程并行执行不同的任务。
  2. 进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
  3. 线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间。
  4. 线程是并发,进程是并行。

线程例

基本操作

#线程基本操作
import threading
import time
def cxk(n):
    print('运行线程:',n)

for i in range(10):# 创建10个线程
    t = threading.Thread(target=cxk, args=(i,))    # 线程运行的函数和参数
    t.setDaemon(True) # 设置为守护线程(在主线程线程结束后自动退出,默认为False即主线程线程结束后子线程仍在执行)
    t.start() # 启动线程

输出:
运行线程: 0
运行线程: 1
运行线程: 2
运行线程: 3
运行线程: 4
运行线程: 5
运行线程: 6
运行线程: 7
运行线程: 8
运行线程: 9

全局变量操作

import threading,time
def cxk(n):
    global j
    j+=1
    time.sleep(1)
    print('运行线程:%s,变量j的情况:%s'%(n,j))
j=-1
for i in range(10):# 创建10个线程
    t = threading.Thread(target=cxk, args=(i,))    # 线程运行的函数和参数
    t.setDaemon(True) # 设置为守护线程(在主线程线程结束后自动退出,默认为False即主线程线程结束后子线程仍在执行)
    t.start() # 启动线程

如果处理速度比较快并不会出现脏数据的情况
>>>
运行线程:0,变量j的情况:0
运行线程:1,变量j的情况:1
运行线程:2,变量j的情况:2
运行线程:3,变量j的情况:3
运行线程:4,变量j的情况:4
运行线程:5,变量j的情况:5
运行线程:6,变量j的情况:6
运行线程:7,变量j的情况:7
运行线程:8,变量j的情况:8
运行线程:9,变量j的情况:9

但是当我们每个进程睡眠加个进去,time.sleep(1),相当于处

理速度比较慢的时候,就会变成下面这样,因为操作的全部线程执行完后第一个线程打印部分还在睡眠,当他打印j变量的时候全部线程已经执行完毕了
>>>
运行线程:0,变量j的情况:9
运行线程:1,变量j的情况:9
运行线程:3,变量j的情况:9
运行线程:5,变量j的情况:9
运行线程:4,变量j的情况:9
运行线程:8,变量j的情况:9
运行线程:7,变量j的情况:9
运行线程:2,变量j的情况:9
运行线程:9,变量j的情况:9
运行线程:6,变量j的情况:9

解决办法就是加锁

# 线程锁
import threading,time
def cxk(n):
    lock.acquire()      # 开始锁
    global j
    j+=1
    time.sleep(1)
    print('运行线程:%s,变量j的情况:%s'%(n,j))
    lock.release()      # 结束锁
j=-1
lock = threading.RLock()    # 定义线程锁
for i in range(10):# 创建10个线程
    t = threading.Thread(target=cxk, args=(i,))    # 线程运行的函数和参数
    t.setDaemon(True) # 设置为守护线程(在主线程线程结束后自动退出,默认为False即主线程线程结束后子线程仍在执行)
    t.start() # 启动线程


#输出
>>>
运行线程:0,变量j的情况:0
运行线程:1,变量j的情况:1
运行线程:2,变量j的情况:2
运行线程:3,变量j的情况:3
运行线程:4,变量j的情况:4
运行线程:5,变量j的情况:5
运行线程:6,变量j的情况:6
运行线程:7,变量j的情况:7
运行线程:8,变量j的情况:8
运行线程:9,变量j的情况:9

那么多线程处理文件的时候会出现文件资源出现问题的情况吗?我们来为每个线程同时向同一个文件写十句话。

import threading,time
def cxk(n):
    with open('cxk.txt','a+') as f:
        for i in range(0,10):
            time.sleep(1)
            f.write('我是线程:%s \n'%str(n))
    print('线程:%s 写入成功'%str(n))
for i in range(10):# 创建10个线程
    t = threading.Thread(target=cxk, args=(i,))    # 线程运行的函数和参数
    t.setDaemon(True) # 设置为守护线程(在主线程线程结束后自动退出,默认为False即主线程线程结束后子线程仍在执行)
    t.start() # 启动线程

由图可以看出没什么问题,并没出现同一文件不能处理,我们加大处理速度试试,睡眠 。

也没什么问题,就是线程完成速度不一样,并没出现第一个线程写完第一句第二个线程接着写第二句,但是这样看起来不像是并行,倒像是串行的。。。我就在想会不会是在并行的情况下,第一个线程睡眠时第二个线程也是同时处于睡眠状态,所以写入也是按顺序的。。。不过我在网上得到下面这一段话:
"""
在Python的原始解释器CPython中存在着GIL,因此在解释执行Python代码时,会产生互斥锁来限制线程对共享资源的访问,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL,所以有GIL效果就是:** 一个进程内同一时间只能允许一个线程进行运算 ** (这尼玛不就是单线程吗?)

python的多线程只能在一个核心上跑(创始人没想到会有多核出现),就是单核的上下文切换,所以很鸡肋。
于是协程在python大展拳脚,好多框架都是使用协程来解决多任务的,而不是线程(scrapy,tornado)。

"""
最后似懂非懂,也就是说到底python的多线程就不是真正的并行。。。

不过python的多线程确实能提升效率,并且使用tkinter时打开不同窗口使用多线程不会产生卡住状态,这篇博客也采用多线程处理,效率大大提升,还有以前的tkinter练习也基本用到了,有兴趣可以去看看。

进程例

进程我用的不多,因为我用notebook运行多进程时只有主进程会显示,子进程调用的函数没反应,只能打包成py文件去cmd下运行。

#写入该句话,运行时直接生成py文件
%%writefile cxkkxc.py
import multiprocessing,time
"""
进程各自持有一份数据,默认无法共享数据
当创建进程时(非使用时),共享数据会被拿到子进程中,当进程中执行完毕后,再赋值给原值。
"""
def cxk(n):
    with open('cxk2.txt','a+') as f:
        for i in range(0,10):
            f.write('我是进程:%s \n'%str(n))
            time.sleep(1)
    print('进程:%s 写入成功'%str(n))
    
if __name__ == "__main__":
    for i in range(1,3):
        p = multiprocessing.Process(target = cxk, args = (i,))
        p.start()
        print("p.pid:", p.pid)
        print ("p.name:", p.name)
        print ("p.is_alive:", p.is_alive())

这里我试用的也是打开文件的形式,只不过是以with open打开的,加了睡眠没有加锁也没出现资源共享问题,搞不懂搞不懂,可能with open 会自动关闭文件吧,每写完一句关闭第二个进程再打开写入。以后再探究探究。最近可能没空咯,参加了一个比赛,等忙完这阵再继续更。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智能视界探索者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值