Linux系统编程学习笔记

PDB的常用的调试命令:

程序先写完的情况的调用方式:

1、 python3  -m pdb test.py

Linux系统编程学习笔记

 #断点的过程  b 7     ## 后面的数字是 行数

 ## = 清楚断点的时候   clear 7  ## 后面的是数字行数

2、其他的一些指令

Linux系统编程学习笔记

  PyCharm,常用的IDE。

3、r ----> return   快速执行到函数的最后一行

 4、还有一种交互式的调用方式

Linux系统编程学习笔记

5、 服务器不停止的情况下,用日志调试法。

  1. 第三个视频 pep8规则

1、

Linux系统编程学习笔记

2、函数和类 之间一般用两个空格隔绝爱,类与类之间一个空格

3、Python3 默认 UTF-8,不应有编码声明。

4、想在一行代码里放两条语句,用分号隔开。

  1. 第五个视频  多任务的理解

1、单核CPU可以同时运行好多的程序的原因是: 利用的时间片轮转、优先级调度。

2、  并行

        并发       两个词汇的理解,一般我们的电脑都是并发的类型。

进程的创建-fork

1、 import  os

       ret = os.fork()       # linux中才有的东西

2、 

Linux系统编程学习笔记

   如图所示就会完成, if 和else 里面的内容一起执行。

3、父进程创建子进程,但是谁先执行还不一定        

4、 ret 这个值是多少?    创建一个子进程,自己本身是一个大于0的值,另一个子进程等于0

      用 cat  加上代码程序.py   就可以在命令行查看代码

Linux系统编程学习笔记

os.getpid()  获取自己的PID,,os.ppid()-- 获取自己父亲的PID                                                    

08父子进程的先后顺序

1、只要主进程执行完毕,就可以打印系统提示

    for example:   多任务,加快程序的运行

Linux系统编程学习笔记

09全局变量在多个子进程中 不共享

1、 全局变量在一个进程中修改,在另一个进程没有影响

Linux系统编程学习笔记

10多次fork问题

1、  fork炸弹:

         while  true:

                os.fork()       # 不要随便执行这个代码,一下子就崩溃

12 Process 创建进程 --- 跨平台的写法

1、以后写创建子进程的方式,不用fork的方式,用这种可以跨平台的方式来写

Linux系统编程学习笔记

13 主进程等待Process里的子进程先结束

1、主进程要等待着 所有的子进程先结束才会over,,儿子孙子都运行完之后才能自己结束!0

14 join 子进程

1、join()⽅法可以等待⼦进程结束后再继续往下运⾏, 通常⽤于进程间的同

  for example:

Linux系统编程学习笔记

 等待 子进程结束以后在去打印 “----main----” 这个主进程的东西

   主进程等待着 子进程的运行,一直在 p.join( ) 这里等待着,称为 堵塞 状态。

    ## 函数说明里面带有 中括号的,就是意味着 可写可不写的状态。

    join([ timeout])    timeout : 等待的最长的时间。

2、p.terminate   不管任务是否完成,立即终止

Linux系统编程学习笔记

15  Process 子进程

1、计算运行程序所花的时间:

      import  time

      time.time()    ##  调用time里面的time()方法,通过两个时间相减就可以得到程序运行所需要的时间。

2、

Linux系统编程学习笔记

程序中,,当 定义一个是实际类后,执行 p.start() ,会首先进入 start()方法里面进行执行,这个方法里面蕴含着调用  run方法,调用run方法之后,创建的子进程就会 执行run()方法

    如果在后面给主程序加上两句代码如下:

      while(true)

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

             time.sleep(1)

    相应的子进程和主进程就会同时执行两个打印过程, 一个打印 -----1----   另一个打印 ----main----- 方法。

16  进程池   -- 非常简单的一种 创建 进程的方法

1、  第一点,先导入:   from  multiprocessing import  Pool

                                       import os,time,random

   po = Pool(3)  # 定义一个进程,最大的进程数是 3

Linux系统编程学习笔记

10个任务交给3个小弟去做, 所以只有先安排的任务做完了,才会有新的进程进入到进程池里面。

 重点需要说的一点: pool.apply_async(worker,(i,))

    pool.close    # 关闭进程池,相当于 不能够再次添加新任务了

    pool.join()    #

Linux系统编程学习笔记

17 创建 进程的总结

1、   ret = os.fork()    #  尽量不要用,非常底层

2、  Process (target = xxxx)

       p1.start()

   ## 通过创建子类来创建 进程

3、 创建进程池,,,推荐使用

    # 主进程一般用来等待,真正的任务一般都在子进程中执行

      pool = Pool (3)   # 经过压力测试,得出一个合适的值。

      pool.apply_async(xxxx)

18  堵塞式添加任务

1、

Linux系统编程学习笔记

图中红色箭头的地方,实际上,当继续执行的时候, 打印出来一个数字,然后创建一个子进程,当去执行子进程的时候,主程序就会卡在原来的位置不变,等到上一个任务执行完之后才会继续添加新任务。  几乎不用的一种方式。

19  进程间的通信- Queue (  队列 )

1、对于队列来说是    先进先出

        还有就是  定义一个队列应该这么定义:    p = Queue(x)   # 里面的 x 代表队列的大小,如果不写的话,意味着你这个队列想要多大都可以,自己随意。

2、 常用的一些方法

     队列可以填充任何的东西,任何东西都是可以往里面添加的

Linux系统编程学习笔记

3、q.get_nowait()

     q.put_nowait()     不需要等待,或者以另外一种方式告诉你  队列已经空了,或者已经满了不能存放其他数据了。

4、进程池中的Queue

     进程池中的通信和普通进程之间的通信大致是一样的,但是需要做两点

      (1)、导入一个模块   from multiprocessing import Manager, Queue

Linux系统编程学习笔记

 换成 Manager 的形式!

(2)、 以下是两种 利用队列进行通信的对比

Linux系统编程学习笔记

Linux系统编程学习笔记

(3)进程池中的通信

Linux系统编程学习笔记

进程与进程之间默认是没有联系的,,要想联系到一起,其中一种方法就是 队列。

二、多线程  (Linux系统编程)

1、使用Thread 完成多线程任务

   1、python 中的一个  Threading 模块,能够很好的实现多线程的任务。

           最简单的例子:      

Linux系统编程学习笔记

 threading模块中的 Thread 函数和上一节课所学的  Process 模块类似,用法也类似,可以实现同时打印五句话。

进程是资源分配的单位,线程是CPU调度的单位。在同一个进程里面完成创建多个线程,进而进行运算,这样的方案能够在现有资源的基础上,实现更高的效率。

Linux系统编程学习笔记

 绿色的称之为 主线程,当主线程运行到 Thread(target = test ),这句话是,就会创建一个额外的子线程(红颜色的箭头),子线程从哪里执行,实际上已经规定好了,就是从 test 开始执行。  主线程在这里其实只是执行了5次for循环,真正打印东西的是  主线程生成的5个子线程。

2、使用Thread子类完成创建多线程

1、多个线程执行一个函数的时候,各自之间不会有影响,各是各的。

2、创建线程的新办法:

 

 创建一个自己的类,以 Thread作为自己的基类,然后将自己要实现的东西放在 类里面的 run方法里面。  

    当后面,创造一个实例之后,执行 t.start() 时,在start方法里面有一个调用 run方法的隐藏,所以就会直接调用 run方法,进而直接执行 类里面的方法。

3、线程的执行顺序

1、

Linux系统编程学习笔记

 当执行完创建线程任务时,这时候有6个线程等待着操作系统去调度,所以这时候谁先被执行呢? 执行顺序和你执行线程没有太大的关系,操作系统说了算!

4、线程共享全局变量

1、  进程: 不管全局变量还是局部变量,统统都是个人是个人的,互相之间没有影响。

        线程:  线程之间共享全局变量。

5、 线程共享全局变量的问题

 (视频出现了问题,播放不了,找一下其他地方的视频补上 )

1、   这种方式  可以解决   之间的通信。

        线程共享全局变量,就会有一些弊端存在!

      

6、 列表当作实参传递线程处理函数中

1、

Linux系统编程学习笔记

  将一个列表当作是一个参数传递到函数里面的时候也是可以共享的, 多线程共享全局变量。

7、进程和线程的对比

1、

Linux系统编程学习笔记

   为什么最后的结果不是 200w次呢?

   操作系统每一次只能执行一句程序,所以当一个程序还没运行完的时候,就已经被赶出来了,所以出现了很多的重叠,所以不是200w次。

8、避免全局变量被修改的方式

1、上面的例子修改的方式:

       第一种方法就是: 使用  sleep,让其中的一个进程进行执行,当执行完之后在继续执行下一个进程,这样就不会出现这种问题了。

2、

Linux系统编程学习笔记

这种方案也非常不错,轮询的方式运行!

9、互斥锁

1、创建互斥锁

Linux系统编程学习笔记

具体上锁:

Linux系统编程学习笔记

threading.Lock(   )    # 里面有两个重要的参数,第一个 blocking 默认为 true:询问一下是否堵塞。

  第二个参数是, timeout ,设定一下运行的时间,默认为 -1,无限等待。

对于上面的代码出现的问题,用互斥锁来解决的方法:

Linux系统编程学习笔记

优点: 当一个进程因为没有抢到上锁而停滞的时候,它不占用CPU,所以相对来说,效率就会变高。

10、大家遇到的问题 (还没有看,明天继续看!)

1、 将上锁放在 for循环里面,这样的话,导致一种现象就是, 每一次执行for循环的时候,两个循环里面都在竞争上锁,降低效率。

Linux系统编程学习笔记

 什么时候加锁?  上锁的代码越少越好。 为什么不是100w,因为每次都在抢着上锁,所以不确定执行的次数。

11、多线程使用非共享变量

1、 threading 模块当中的 current_thread()方法 的名字就是当前线程里面的名字。

2、虽然两个线程都到同一个函数里面去执行,但是个人是个人的变量,互相不影响。

     去看一下文档里面的代码,然后反思一下。

12、死锁以及解决办法

1、看门狗 的原理,,添加一个变量。

13、同步的理解已经使用

1、同步就是协同步调,按预定的先后次序进行运行。 异步: 不确定先后的顺序。

2、用 互斥锁实现“同步” 的方法:

Linux系统编程学习笔记

14、生产者与消费者来解决耦合问题

                 解耦在写代码的过程中非常重要!

1、 第一个导入队列模块:(队列: 先进先出 )

      python3 中应该这么写:  from queue import Queue 

      python2 中应该这么写:  from Queue import Queue

2、 线程中的队列创建方式:  queue = Queue( )

              ----- 队列的基本操作: queue.put()   queue.get()    queue.qsize()   queue.put_nowait()

      生产者与消费者之间的关系的一个完整的代码形式:

Linux系统编程学习笔记

 队列就是用来 给 生产者和消费者之间解耦用的

15、ThreadLocal对象在线程中的使用

1、使用全局字典的方法

Linux系统编程学习笔记

   这种方案可以实现,但是非常的费劲,所以下一种方法应运而生

2、ThreadLocal 方法

Linux系统编程学习笔记

    当两个线程都需要对全局变量进行操作的时候,就可以联想这个ThreadLocal 方法的使用。

         对属性设置一个值,这一点需要自己课下好好的回顾一下

 

15、异步的实现

1、实现代码好好看看

Linux系统编程学习笔记

异步: 就是当我正在做着某件事情的时候,突然通知我去做其他的事情, 这种情况叫做 异步。

    上述代码的原理:

     1)、 主进程一直在睡觉,当 子进程执行完毕的时候,主进程醒来,直接去执行 test2 ,, 子进程在结束的时候,会传递一个  “hahaha” 给test2(主进程), 这种情况叫做 异步。

      2)、 定义一个 线程池,,  然后调用   pool.apply_async( func = test,callback = test2): 这句代码的解释是:   前面的 func = test,就相当于直接写 一个 test,, 后面的 callback 意思是 回调,主进程去干的事情。

16、GIL的问题 ---  全局解释器锁

1、 多进程的效率明显大于 多线程的效率, 对于单核来说没必要,但是对于多核来说 至关重要。

2、 如何解决这个问题呢?

       接下来首先需要了解一下的是, 如何在Ubuntu系统中写C语言程序:

        以后在开发的过程中,无论是从网上当下来一个 C语言程序还是其他的,首先都要去重视一下 read.me 文件,用代码  cat  read.me   就可以读出来该 C语言程序应该如何执行以及运行在什么环境下。 切记这一点!

Linux系统编程学习笔记

     克服Python中死循环的问题:   死循环用C语言来写,这样能使得程序的执行效率达到很高的程度。