首页 > 编程语言 >多线程python

多线程python

时间:2023-07-06 21:23:59浏览次数:46  
标签:__ name start python print 线程 进程 多线程

如何开启进程

使用的是内置的模块:multiprocess
from multiprocessing import Process


def task():
    with open('a.txt', 'w', encoding="utf8") as f:
        f.write('helloworld')


# 开一个进程来执行task这个任务

# 如何开进程
"""在Windows系统中,开启进程必须写在__main__中, 在其他系统中不用加"""
if __name__ == '__main__':
    p = Process(target=task)  # 得到一个对象,还没有开启进程呢,知识实例化了一个进程对象

    p.start()  # 调用这个方法才是真正的开启进程

# 总结  
1 开启进程调用的是multiprocessing 模块 中的process类,
2 在windows 中, 开启进程必须写在__main__中,别的系统不需要
3 要开启进程,就需要先得到一个进程对象, a = Process(target=aaa)
4 得到进程对象之后,进程对象名 调用start方法,开启进程 a.start() 

如何开启多进程

import time
from multiprocessing import Process


def task(i):
    print(f'第{i}次')
    import time
    time.sleep(1)


if __name__ == '__main__':
    start_time = time.time()
    ll = []
    for i in range(5):
        p = Process(target=task, args=(i,))  # 通知操作系统开启进程,开启的时间有快有慢,所以顺序可能不一样
        p.start()
        ll.append(p)  # 把每个进程对象都加入ll,然后统一给他们加入join

    for j in ll:
        j.join()  # join 子线程运行完之后,再运行主线程

    print(123)
    print(time.time() - start_time)

"""
1 开启多进程,如果想要将子进程运行完毕后再运行主进程,就将所有子进程加入到列表,然后统一给他们添加join方法。
2 如果不想让主进程等待子进程,就不用加join方法
"""

Process类的参数

from multiprocessing import Process
import time

def task(name, age, gender):
    print(name)
    print(age)
    print(gender)


if __name__ == "__main__":
    """
    name参数 ,调用方法,p.name 修改进程名字,不传就是默认进程名字
    *args 参数 args = ()  传入的必须是元组 如果只有一个参数,那必须加逗号,不然会被认为是一个字符串
    **kwargs 参数 kwargs = {}  必须用字典格式传参数
    daemon :  p.daemon = Ture 守护进程 作用:主进程结束,子进程也跟着结束。daemon必须写在start之前
    """
    # 开启的这个叫做子进程,开启进程以外的是主进程,
    p = Process(target=task, name='bb_1', args=('ben',), kwargs={'age': 18, 'gender': 'male'})
    # p.daemon = True  # 守护进程的作用,主进程结束,子进程也跟着结束
    p.start()
    # time.sleep(1)
    # 如果这里加了等待,根据cpu的切换工作机制,会先去执行子进程再回来执行主进程,没加入等待,直到主进程执行完才执行子进程
    # for i in range(10000):
    #     print(' ')
    print(123)
    print(p.name)  # Process-1  默认进程名字

"""
先执行了主进程里面的程序,如果在主进程中加入个等待1秒,
按照cpu的轮换执行机制,会先去执行子程序,然后再回来执行主程序  
"""

"""
总结: 子进程传参数必须用关键字传参数 ,位置参数args必须传元组 ,kwargs 必须传字典格式
传递位置参数 args 必须是元组的形式,有几个参数,函数里的参数就写几个参数,(如果元组内只有一个参数,那就加个 , 逗号)
传递关键字参数 kwargs 就写k值再函数的参数中
daemon = True 守护进程 ,p.daemon=True  必须写在start的前面, 主进程结束,子进程也必须结束 
daemon必须写在start上面
p.start()  这里才是开启了进程
"""

 

方法介绍

from multiprocessing import Process
import time


def task():
    print('123')
    time.sleep(5)


if __name__ == '__main__':
    p = Process(target=task())
    p.start()

    # ···············
    # p.terminate()  # 杀死进程

    # ···············
    # time.sleep(1)
    # print(p.is_alive())  # False 看一个进程是否存活 如果前面不加sleep,会返回true 因为没来的及杀死
    # ···············
    p.join()  # 等子进程运行完后,再运行另外线程
    print('456')
    # 主进程和子进程之间的关系是相互独立的

"""
● p.start():启动进程,并调用该子进程中的p.run()
● p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
● p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
● p.is_alive():如果p仍然运行,返回True
● p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
"""

进程锁

# 锁:遇到的所有关于加锁的都是为了保证数据的安全

MySQL中:行锁、表锁、悲观锁、乐观锁、等
进程锁、互斥锁、GIL锁、死锁等

# 加锁的目的是为了让数据更安全

def task(i, lock):
    # 上一把锁
    lock.acquire()
    print('第%s个进程进来了' % i)
    print('第%s个进程走了' % i)
    lock.release()  # 释放锁


from multiprocessing import Lock
from multiprocessing import Process

if __name__ == '__main__':
    lock = Lock()  # 得到一个锁对象。
    for i in range(5):
        p = Process(target=task, args=(i, lock))
        p.start()

"""
用法:在主进程中得到一个锁对象,然后传给子进程,在子进程中通过锁定和释放来确保数据的安全性
from multiprocessing import lock
lock = lock()
lock = acquire()上锁 
lock = release()释放锁

总结: 
进程锁 是一种用于控制并发访问共享资源的机制,它主要的目的是防止多个进程同时修改和访问共享资源导致的数据不一致或者竞态条件

进程锁通过提供互斥访问的机制来解决这些问题,当一个进程获得了进程锁后,其他进程必须等待该进程释放锁才能继续访问共享资源
这样可以确保在任意时刻只有一个进程可以访问共享资源,从而避免了访问并发导致的问题

进程锁的意义在于保护共享资源的完整性和一致性。它确保了多个进程在并发访问共享资源时的顺序和互斥性,
避免了竞态条件和数据不一致的情况发生。进程锁是实现多进程并发安全的重要工具之一。

"""

 

 

 

 

 

如何开启线程

方式一:
def task():
    print('我是线程')


from multiprocessing import Process
from threading import Thread

if __name__ == '__main__':
    t = Thread(target=task)  
    t.start()  # 启动线程
    print('主线程')
    
    
方式二:
from threading import Thread
import time
class Sayhi(Thread):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        time.sleep(2)
        print('%s say hello' % self.name)

if __name__ == '__main__':
    t = Sayhi('ly')
    t.start()
    t.daemon = True     # 线程守护,主线程结束后,子线程也结束。
    # t.setDaemon(True)  # 守护线程:主线程结束,子线程跟着结束
    print('主线程')
    
  #####几个方法
    # print(t.isAlive()) 看线程是否存在
    # print(t.is_alive())    看线程是否存在
    # print(t.getName()) 获取线程名字
    # print(t.name) 获取线程名字
    # t.setName('ly_2') 设置线程名字
    # print(t.getName()) 获取线程名字
    print(threading.currentThread().getName())  #: 返回当前的线程变量。
    print(threading.enumerate()[0].getName())  #: 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
    print(threading.activeCount())  #: 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

如何开启多线程

from threading import Thread


def task(i):
    print(f'子线程{i}')


if __name__ == '__main__':
    ll = []
    for i in range(5):
        t = Thread(target=task, args=(i,))
        t.start()
        ll.append(t)

    for j in ll:
        j.join()

    print('主进程')

线程与进程的区别

1 线程共享创建它的进程的地址空间; 进程具有自己的地址空间。
2 线程可以直接访问其进程的数据段; 进程具有其父进程数据段的副本。
3 线程可以直接与其进程中的其他线程通信; 进程必须使用进程间通信与同级进程进行通信。
4 新线程很容易创建; 新进程需要复制父进程。
5 线程可以对同一进程的线程行使相当大的控制权。 进程只能控制子进程。
6 对主线程的更改(取消,优先级更改等)可能会影响该进程其他线程的行为; 对父进程的更改不会影响子进程。
····································································
1. 进程的开销远远大于线程的开销
2. 进程之间的数据是隔离的,线程之间的数据呢? 线程之间的数据是共享的,严格的来说:同一个进程下的线程之间的数据是共享的
3. 想让不同进程之间的线程之间的数据共享------->还是让进程之间通信------->线程之间也通信了--->队列

 

标签:__,name,start,python,print,线程,进程,多线程
From: https://www.cnblogs.com/xiaoyou898/p/17533359.html

相关文章

  • Logistic回归模型,python
    代码参考https://blog.csdn.net/DL11007/article/details/129204192?ops_request_misc=&request_id=&biz_id=102&utm_term=logistic%E6%A8%A1%E5%9E%8Bpython&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-129204192.142^v......
  • Python中标准输入(stdin)、标准输出(stdout)、标准错误(stdout)的用法
    1.标准输入input()、raw_input()Python3.x中input()函数可以实现提示输入,python2.x中要使用raw_input(),例如:foo=input("Enter:")#python2.x要用raw_input()print("Youinput:[%s]"%(foo))#测试执行Enter:abcdeYouinput:[abcde]#读取一行(不......
  • Python中os.system()、subprocess.run()、call()、check_output()的用法
    1.os.system()os.system()是对C语言中system()系统函数的封装,允许执行一条命令,并返回退出码(exitcode),命令输出的内容会直接打印到屏幕上,无法直接获取。示例:#test.pyimportosos.system("ls-l|greptest")#允许管道符#测试执行$ll<=======......
  • Python中startswith()和endswith()方法
    startswith()方法startswith()方法用于检索字符串是否以指定字符串开头,如果是返回True;反之返回False。endswith()方法endswith()方法用于检索字符串是否以指定字符串结尾,如果是则返回True;反之则返回Falses='helloword'print("s.startswith('wor'):",s.startswith('wor......
  • 【Python】多维列表变为一维列表的方法--numpy
    转载:(18条消息)【Python】多维列表变为一维列表的方法_四维列表变一维_Vincent__Lai的博客-CSDN博客题目给定一个多维列表,怎么让其变为一维?例如,输入:[[1,4],[2],[3,5,6]],输出:[1,4,2,3,5,6]常规一行做法a=[[1,4],[2],[3,5,6]]a=[jforiinaforjini......
  • 将PYTHON包环境从一个电脑拷贝到另外一个电脑
    将PYTHON包环境从一个电脑拷贝到另外一个电脑1、在当前电脑复制D:\ProgramFiles\Python\Python311\Lib中的所有文件生成myrequirement.txt文件pipfreeze>myrequirement.txtmyrequirement.txt文件如下:colorama==0.4.6constantly==15.1.0cpca==0.5.5cryptography=......
  • python pydoc模块生成html网页版内容
    pydoc是一个能生成网页版的模块,内置模块命令:python-mpydoc-p1234-m加载模块-p网页访问端口命令行:b打开浏览器q退出效果:Windows环境下:python-mpydoc-watexit//在当前目录创建atexit.htmlpython-mpydoc-p5000//启动一个Web服务器监听h......
  • CPython, Pypy, MicroPython...还在傻傻分不清楚?
    哈喽大家好,我是咸鱼当我们说Python时,通常指的是官方实现的CPython但还有很多比如Pypy、Jython、MicroPython、Brython、RustPython等“python”许多小伙伴看到这些带“python”的概念可能一头雾水,心想这跟我平时接触到的python有什么区别吗?这些到底是什么那么今天这......
  • Python如何实现docstring
    docPython语言从排版上看强制要求了一些书写规范,算是强制赋予了每个程序员一个"代码洁癖"。作为规范的一部分,可以在在类函数的开始增加注释,并且语言本身为这种注释做了"背书":可以通过help展示这个帮助文档的内容。这个本来是Python一个很细小的功能,也是一个很有意思的语法糖(因......
  • Python3读写TOML文件
    TOML(Tom'sObvious,MinimalLanguage)是一种易于阅读和编写的配置文件格式。它的设计目标是提供一种简单而灵活的方式来表示配置数据,以便于人类阅读和编辑。基础示例#config.toml[server]host="localhost"port=8080[database]name="mydb"user="myuser"passwor......