事倍功半是蠢蛋05:python开发日记

pip更换清华源镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

pip show pip

pycharm管理员模式打开可以规避poetry install时候的权限问题

ctrl + shift + v 获取剪贴板

20250409 进阶python
https://github.com/ateliershen/Python-100-Days-zh_TW/blob/master/Day01-15/09.面向对象进阶.md
双下划线开头方法外部类不能用 单下划线方法约定俗成 不建议用

__slots__用法

@property包装 getter/setter

文件流

临时文件

json模組主要有四個比較重要的函式,分別是:

dump - 將Python物件按照JSON格式序列化到檔案中
dumps - 將Python物件處理成JSON格式的字串
load - 將檔案中的JSON資料反序列化成物件
loads - 將字串的內容反序列化成Python物件
這裡出現了兩個概念,一個叫序列化,一個叫反序列化。自由的百科全書維基百科上對這兩個概念是這樣解釋的:“序列化(serialization)在計算機科學的資料處理中,是指將資料結構或物件狀態轉換為可以儲存或傳輸的形式,這樣在需要的時候能夠恢復到原先的狀態,而且透過序列化的資料重新獲取位元組時,可以利用這些位元組來產生原始物件的副本(複製)。與這個過程相反的動作,即從一系列位元組中提取資料結構的操作,就是反序列化(deserialization)”。

我一直没有系统性学习多线程。

def download_task(filename):
    print('啟動下載程序,程序號[%d].' % getpid())
    print('開始下載%s...' % filename)
    time_to_download = randint(5, 10)
    sleep(time_to_download)
    print('%s下載完成! 耗費了%d秒' % (filename, time_to_download))


def main():
    start = time()
    p1 = Process(target=download_task, args=('Python從入門到住院.pdf', ))
    p1.start()
    p2 = Process(target=download_task, args=('Peking Hot.avi', ))
    p2.start()
    p1.join()
    p2.join()
    end = time()
    print('總共耗費了%.2f秒.' % (end - start))


if __name__ == '__main__':
    main()
from multiprocessing import Process
from time import sleep

counter = 0


def sub_task(string):
    global counter
    while counter < 10:
        print(string, end='', flush=True)
        counter += 1
        sleep(0.01)

        
def main():
    Process(target=sub_task, args=('Ping', )).start()
    Process(target=sub_task, args=('Pong', )).start()


if __name__ == '__main__':
    main()

看起來沒毛病,但是最後的結果是Ping和Pong各輸出了10個,Why?當我們在程式中建立程序的時候,子程序複製了父程序及其所有的資料結構,每個子程序有自己獨立的記憶體空間,這也就意味著兩個子程序中各有一個counter變數,所以結果也就可想而知了。要解決這個問題比較簡單的辦法是使用multiprocessing模組中的Queue類,它是可以被多個程序共享的佇列,底層是透過管道和訊號量(semaphore)機制來實現的,有興趣的讀者可以自己嘗試一下。

import threading
import time

# 不使用锁的版本 - 会导致错误结果
def without_lock():
    # 共享资源
    counter = 0
    
    def increment():
        nonlocal counter
        current = counter
        time.sleep(0.001)  # 模拟处理延迟
        counter = current + 1
    
    # 创建10个线程
    threads = []
    for _ in range(10):
        t = threading.Thread(target=increment)
        threads.append(t)
        t.start()
    
    # 等待所有线程结束
    for t in threads:
        t.join()
    
    print(f"不使用锁的结果: {counter} (应该是10)")

# 使用锁的版本 - 得到正确结果
def with_lock():
    # 共享资源
    counter = 0
    lock = threading.Lock()
    
    def increment():
        nonlocal counter
        with lock:  # 使用锁保护临界区
            current = counter
            time.sleep(0.001)  # 模拟处理延迟
            counter = current + 1
    
    # 创建10个线程
    threads = []
    for _ in range(10):
        t = threading.Thread(target=increment)
        threads.append(t)
        t.start()
    
    # 等待所有线程结束
    for t in threads:
        t.join()
    
    print(f"使用锁的结果: {counter} (正确为10)")

if __name__ == '__main__':
    without_lock()
    with_lock()

如何分析任务是IO密集型还是CPU密集型

特性 IO密集型 CPU密集型
主要瓶颈 等待输入/输出操作 计算处理能力
资源使用 CPU大部分时间空闲 CPU使用率高
适合并发方式 多线程/异步IO 多进程

IO密集型任务特征:
频繁的文件操作(读/写文件)
网络请求和数据传输
数据库操作
用户输入等待
程序运行时CPU使用率低
任务耗时与数据量成比例
CPU密集型任务特征:
复杂数学计算(如加密、压缩)
图形/图像处理
科学计算和模拟
大规模数据处理
程序运行时CPU使用率高
任务耗时与计算复杂度成比例

posted @ 2025-02-25 17:39  空心橙子  阅读(20)  评论(0)    收藏  举报