Trăn đồng thời

Có nhiều lý do khiến ứng dụng của bạn có thể bị chậm. Đôi khi điều này là do thiết kế thuật toán kém hoặc lựa chọn sai cấu trúc dữ liệu. Tuy nhiên, đôi khi, đó là do các yếu tố nằm ngoài tầm kiểm soát của chúng tôi, chẳng hạn như hạn chế về phần cứng hoặc các vấn đề về kết nối mạng. Đó là nơi đồng thời và song song phù hợp. Chúng cho phép các chương trình của bạn thực hiện nhiều việc cùng một lúc, đồng thời hoặc bằng cách lãng phí ít thời gian nhất có thể để chờ đợi các tác vụ bận rộn

Cho dù bạn đang xử lý các tài nguyên web bên ngoài, đọc và ghi vào nhiều tệp hay cần sử dụng một hàm chuyên sâu về tính toán nhiều lần với các tham số khác nhau, thì bài viết này sẽ giúp bạn tối đa hóa hiệu quả và tốc độ mã của mình

Đầu tiên, chúng ta sẽ tìm hiểu xem đồng thời và song song là gì và cách chúng phù hợp với lĩnh vực Python bằng cách sử dụng các thư viện tiêu chuẩn như luồng, đa xử lý và asyncio. Phần cuối cùng của bài viết này sẽ so sánh việc triển khai Python của ________ 04/________ 05 với cách các ngôn ngữ khác đã triển khai chúng

Bạn có thể tìm thấy tất cả các mã ví dụ từ bài viết này trong repo concurrency-parallelism-and-asyncio trên GitHub

Để làm việc với các ví dụ trong bài viết này, bạn nên biết cách làm việc với các yêu cầu HTTP

mục tiêu

Đến cuối bài viết này, bạn sẽ có thể trả lời các câu hỏi sau

  1. đồng thời là gì?
  2. một chủ đề là gì?
  3. Điều đó có nghĩa là gì khi một cái gì đó không bị chặn?
  4. Vòng lặp sự kiện là gì?
  5. Gọi lại là gì?
  6. Tại sao phương thức asyncio luôn nhanh hơn một chút so với phương thức luồng?
  7. Khi nào bạn nên sử dụng luồng và khi nào bạn nên sử dụng asyncio?
  8. song song là gì?
  9. Sự khác biệt giữa đồng thời và song song là gì?
  10. Có thể kết hợp asyncio với đa xử lý không?
  11. Khi nào bạn nên sử dụng đa xử lý so với asyncio hoặc phân luồng?
  12. Sự khác biệt giữa đa xử lý, không đồng bộ và đồng thời là gì. tương lai?
  13. Làm cách nào để kiểm tra asyncio bằng pytest?

đồng thời là gì?

Một định nghĩa hiệu quả cho đồng thời là "có thể thực hiện nhiều tác vụ cùng một lúc". Tuy nhiên, đây là một chút sai lệch, vì các tác vụ có thể thực sự được thực hiện hoặc không thực sự được thực hiện cùng một lúc. Thay vào đó, một quy trình có thể bắt đầu, sau đó khi nó đang đợi một hướng dẫn cụ thể kết thúc, hãy chuyển sang một tác vụ mới, chỉ quay lại khi nó không còn chờ nữa. Khi một nhiệm vụ hoàn thành, nó lại chuyển sang nhiệm vụ chưa hoàn thành cho đến khi tất cả chúng được thực hiện. Các tác vụ bắt đầu không đồng bộ, được thực hiện không đồng bộ và sau đó kết thúc không đồng bộ

Nếu điều đó làm bạn bối rối, thay vào đó hãy nghĩ về một phép loại suy. Giả sử bạn muốn tạo một BLT. Đầu tiên, bạn sẽ muốn ném thịt xông khói vào chảo ở nhiệt độ trung bình thấp. Trong khi nấu thịt xông khói, bạn có thể lấy cà chua và rau diếp ra và bắt đầu sơ chế [rửa và cắt] chúng. Trong khi đó, bạn tiếp tục kiểm tra và thỉnh thoảng lật miếng thịt xông khói của mình

Tại thời điểm này, bạn đã bắt đầu một nhiệm vụ, sau đó bắt đầu và hoàn thành hai nhiệm vụ khác trong thời gian chờ đợi, tất cả trong khi bạn vẫn đang đợi ở nhiệm vụ đầu tiên

Cuối cùng, bạn đặt bánh mì của bạn trong một máy nướng bánh mì. Trong khi nướng, bạn tiếp tục kiểm tra thịt xông khói của mình. Khi các miếng đã hoàn thành, bạn lấy chúng ra và bày lên đĩa. Sau khi nướng xong bánh mì, bạn phết lên bánh sandwich mà bạn chọn, sau đó bạn có thể bắt đầu xếp lớp trên cà chua, rau diếp, và sau đó, sau khi nấu xong, là thịt xông khói của bạn. Chỉ sau khi mọi thứ đã được nấu chín, chuẩn bị và xếp lớp, bạn mới có thể đặt miếng bánh mì nướng cuối cùng lên bánh sandwich của mình, cắt lát [tùy chọn] và ăn

Bởi vì nó yêu cầu bạn thực hiện nhiều nhiệm vụ cùng một lúc, nên việc tạo BLT vốn dĩ là một quá trình đồng thời, ngay cả khi bạn không tập trung hoàn toàn vào từng nhiệm vụ đó cùng một lúc. Đối với tất cả ý định và mục đích, trong phần tiếp theo, chúng tôi sẽ đề cập đến hình thức tương tranh này chỉ là "tương tranh. " Chúng ta sẽ phân biệt nó sau trong bài viết này

Vì lý do này, tính đồng thời rất phù hợp cho các quy trình sử dụng nhiều I/O -- các tác vụ liên quan đến việc chờ yêu cầu web hoặc thao tác đọc/ghi tệp

Trong Python, có một số cách khác nhau để đạt được đồng thời. Đầu tiên chúng ta sẽ xem xét thư viện luồng

Đối với các ví dụ của chúng ta trong phần này, chúng ta sẽ xây dựng một chương trình Python nhỏ lấy một thể loại nhạc ngẫu nhiên từ API Trình tạo nhạc của Binary Jazz năm lần, in thể loại đó ra màn hình và đặt từng thể loại vào tệp riêng của nó

Để làm việc với luồng trong Python, lần nhập duy nhất bạn cần là

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
6, nhưng với ví dụ này, tôi cũng đã nhập
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
7 để làm việc với các yêu cầu HTTP,
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
8 để xác định thời gian hoàn thành các chức năng và
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
9 để dễ dàng chuyển đổi

Bạn có thể tìm mã cho ví dụ này tại đây

Hãy bắt đầu với một chức năng đơn giản

def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    req = Request["//binaryjazz.us/wp-json/genrenator/v1/genre/", headers={"User-Agent": "Mozilla/5.0"}]
    genre = json.load[urlopen[req]]

    with open[file_name, "w"] as new_file:
        print[f"Writing '{genre}' to '{file_name}'..."]
        new_file.write[genre]

Kiểm tra mã ở trên, chúng tôi đang yêu cầu API Genrenator, tải phản hồi JSON của nó [một thể loại nhạc ngẫu nhiên], in nó, sau đó ghi nó vào một tệp

Nếu không có tiêu đề "Tác nhân người dùng", bạn sẽ nhận được 304

Điều chúng tôi thực sự quan tâm là phần tiếp theo, nơi diễn ra phân luồng thực tế

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]

Đầu tiên chúng ta bắt đầu với một danh sách. Sau đó, chúng tôi tiến hành lặp lại năm lần, mỗi lần tạo một chuỗi mới. Tiếp theo, chúng tôi bắt đầu từng luồng, nối nó vào danh sách "luồng" của chúng tôi, sau đó lặp lại danh sách của chúng tôi lần cuối để tham gia từng luồng

Giải trình. Tạo chủ đề trong Python thật dễ dàng

Để tạo một chủ đề mới, hãy sử dụng

async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
0. Bạn có thể chuyển vào đó kwarg [đối số từ khóa]
async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
1 với giá trị của bất kỳ chức năng nào bạn muốn chạy trên chuỗi đó. Nhưng chỉ chuyển vào tên của hàm, không phải giá trị của nó [có nghĩa là, đối với mục đích của chúng tôi,
async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
2 chứ không phải
async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
3]. Để chuyển các đối số, hãy chuyển vào "kwargs" [lấy lệnh của kwargs của bạn] hoặc "args" [lấy một lần lặp có chứa các đối số của bạn -- trong trường hợp này là một danh sách]

Tuy nhiên, tạo một chủ đề không giống như bắt đầu một chủ đề. Để bắt đầu chủ đề của bạn, hãy sử dụng

async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
4. Bắt đầu một luồng có nghĩa là "bắt đầu thực hiện nó. "

Cuối cùng, khi chúng tôi tham gia chuỗi với

async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
5, tất cả những gì chúng tôi đang làm là đảm bảo chuỗi đã kết thúc trước khi tiếp tục với mã của chúng tôi

chủ đề

Nhưng chính xác những gì là một chủ đề?

Chuỗi là một cách cho phép máy tính của bạn chia nhỏ một quy trình/chương trình thành nhiều phần nhẹ thực thi song song. Hơi khó hiểu, việc triển khai luồng giới hạn tiêu chuẩn của Python chỉ có thể thực thi một luồng tại một thời điểm do một thứ gọi là Khóa phiên dịch toàn cầu [GIL]. GIL là cần thiết vì quản lý bộ nhớ của CPython [triển khai mặc định của Python] không an toàn cho luồng. Do giới hạn này, luồng trong Python là đồng thời, nhưng không song song. Để giải quyết vấn đề này, Python có một mô-đun

async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
6 riêng biệt không bị giới hạn bởi GIL, mô-đun này tạo ra các quy trình riêng biệt, cho phép thực thi song song mã của bạn. Sử dụng mô-đun
async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
6 gần giống như sử dụng mô-đun
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
6

Thông tin thêm về GIL của Python và an toàn luồng có thể được tìm thấy trên Real Python và tài liệu chính thức của Python

Chúng ta sẽ sớm tìm hiểu sâu hơn về đa xử lý trong Python

Trước khi chúng tôi chỉ ra khả năng cải thiện tốc độ đối với mã không theo luồng, tôi đã tự do tạo một phiên bản không theo luồng của cùng một chương trình [một lần nữa, có sẵn trên GitHub]. Thay vì tạo một luồng mới và nối từng luồng, thay vào đó, nó gọi

async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
2 trong vòng lặp for lặp lại năm lần

Để so sánh các điểm chuẩn tốc độ, tôi cũng đã nhập thư viện

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
8 để tính thời gian thực thi các tập lệnh của chúng tôi

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
9

Khi chạy tập lệnh, chúng tôi thấy rằng máy tính của tôi mất khoảng 1. 49 giây [cùng với các thể loại nhạc cổ điển như "dutch hat industrialtune"]. Không tệ lắm

Bây giờ, hãy chạy phiên bản sử dụng luồng

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds

Điều đầu tiên có thể nổi bật với bạn là các chức năng không được hoàn thành theo thứ tự. 2 - 0 - 4 - 1 - 3

Điều này là do bản chất không đồng bộ của luồng. khi một chức năng chờ đợi, một chức năng khác bắt đầu, v.v. Vì chúng tôi có thể tiếp tục thực hiện các tác vụ trong khi chờ người khác hoàn thành [do hoạt động kết nối mạng hoặc tệp I/O], bạn cũng có thể nhận thấy rằng chúng tôi đã cắt giảm khoảng một nửa thời gian của mình. 0. 77 giây. Mặc dù hiện tại điều này có vẻ không nhiều, nhưng thật dễ dàng để tưởng tượng trường hợp thực tế khi xây dựng một ứng dụng web cần ghi nhiều dữ liệu hơn vào một tệp hoặc tương tác với các dịch vụ web phức tạp hơn nhiều

Vì vậy, nếu threading là tuyệt vời, tại sao chúng ta không kết thúc bài viết ở đây?

Bởi vì có nhiều cách tốt hơn để thực hiện các tác vụ đồng thời

không đồng bộ

Hãy xem một ví dụ sử dụng asyncio. Đối với phương pháp này, chúng tôi sẽ cài đặt aiohttp bằng cách sử dụng

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
11. Điều này sẽ cho phép chúng tôi thực hiện các yêu cầu không chặn và nhận phản hồi bằng cách sử dụng cú pháp
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 sẽ sớm được giới thiệu. Nó cũng có thêm lợi ích là chức năng chuyển đổi phản hồi JSON mà không cần nhập thư viện
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
9. Chúng tôi cũng sẽ cài đặt và nhập aiofiles, cho phép các thao tác với tệp không bị chặn. Ngoài
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
15 và
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
16, hãy nhập
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
17, đi kèm với thư viện chuẩn Python

"Không chặn" có nghĩa là một chương trình sẽ cho phép các luồng khác tiếp tục chạy trong khi chờ đợi. Điều này trái ngược với mã "chặn", dừng hoàn toàn việc thực thi chương trình của bạn. Hoạt động I/O bình thường, đồng bộ bị giới hạn này

Bạn có thể tìm mã cho ví dụ này tại đây

Khi chúng tôi đã nhập xong, hãy xem phiên bản không đồng bộ của hàm

async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
2 từ ví dụ asyncio của chúng tôi

________số 8

Đối với những người không quen thuộc với cú pháp

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 có thể tìm thấy trong nhiều ngôn ngữ hiện đại khác,
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4 tuyên bố rằng một hàm, vòng lặp
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
32 hoặc câu lệnh
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
33 phải được sử dụng không đồng bộ. Để gọi một hàm không đồng bộ, bạn phải sử dụng từ khóa
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 từ một hàm không đồng bộ khác hoặc gọi trực tiếp
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
35 từ vòng lặp sự kiện, có thể lấy từ
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
36 -- i. e. ,
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
37

Ngoài ra

  1. Starting...
    Writing "college k-dubstep" to "./threading/new_file2.txt"...
    Writing "swiss dirt" to "./threading/new_file0.txt"...
    Writing "bop idol alternative" to "./threading/new_file4.txt"...
    Writing "ethertrio" to "./threading/new_file1.txt"...
    Writing "beach aust shanty français" to "./threading/new_file3.txt"...
    Time to complete threading read/writes: 0.77 seconds
    
    38 cho phép chờ phản hồi không đồng bộ và thao tác với tệp
  2. Starting...
    Writing "college k-dubstep" to "./threading/new_file2.txt"...
    Writing "swiss dirt" to "./threading/new_file0.txt"...
    Writing "bop idol alternative" to "./threading/new_file4.txt"...
    Writing "ethertrio" to "./threading/new_file1.txt"...
    Writing "beach aust shanty français" to "./threading/new_file3.txt"...
    Time to complete threading read/writes: 0.77 seconds
    
    39 [không được sử dụng ở đây] lặp qua luồng không đồng bộ

Vòng lặp sự kiện

Các vòng lặp sự kiện là các cấu trúc vốn có của lập trình không đồng bộ cho phép thực hiện các tác vụ không đồng bộ. Khi bạn đang đọc bài viết này, tôi có thể yên tâm cho rằng bạn có thể không quá quen thuộc với khái niệm này. Tuy nhiên, ngay cả khi bạn chưa bao giờ viết một ứng dụng không đồng bộ, bạn vẫn có kinh nghiệm với các vòng lặp sự kiện mỗi khi sử dụng máy tính. Cho dù máy tính của bạn đang lắng nghe đầu vào bàn phím, bạn đang chơi trò chơi nhiều người chơi trực tuyến hay bạn đang duyệt Reddit trong khi đang sao chép tệp ở chế độ nền, vòng lặp sự kiện là động lực giúp mọi thứ hoạt động trơn tru và hiệu quả. Về bản chất thuần túy nhất, vòng lặp sự kiện là một quá trình chờ đợi các yếu tố kích hoạt và sau đó thực hiện các hành động [được lập trình] cụ thể sau khi các yếu tố kích hoạt đó được đáp ứng. Chúng thường trả về một số loại "lời hứa" [cú pháp JavaScript] hoặc "tương lai" [cú pháp Python] để biểu thị rằng một tác vụ đã được thêm vào. Khi tác vụ kết thúc, lời hứa hoặc tương lai trả về một giá trị được truyền lại từ hàm được gọi [giả sử hàm đó trả về một giá trị]

Ý tưởng thực hiện một chức năng để đáp lại một chức năng khác được gọi là "gọi lại. "

Đối với một cuộc gọi lại và sự kiện khác, đây là một câu trả lời tuyệt vời trên Stack Overflow

Đây là hướng dẫn về chức năng của chúng tôi

Chúng tôi đang sử dụng

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
38 để mở phiên máy khách của mình một cách không đồng bộ. Lớp
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
21 là lớp cho phép chúng tôi thực hiện các yêu cầu HTTP và duy trì kết nối với nguồn mà không chặn việc thực thi mã của chúng tôi. Sau đó, chúng tôi thực hiện một yêu cầu không đồng bộ với API Genrenator và chờ phản hồi JSON [một thể loại nhạc ngẫu nhiên]. Trong dòng tiếp theo, chúng tôi sử dụng lại
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
38 với thư viện
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
16 để mở một tệp mới không đồng bộ để ghi thể loại mới của chúng tôi vào. Chúng tôi in thể loại, sau đó ghi nó vào tệp

Không giống như các tập lệnh Python thông thường, lập trình với asyncio thực thi khá nhiều* bằng cách sử dụng một số loại chức năng "chính"

*Trừ khi bạn đang sử dụng cú pháp "lợi nhuận" không dùng nữa với @asyncio. trình trang trí coroutine, sẽ bị xóa trong Python 3. 10

Điều này là do bạn cần sử dụng từ khóa "không đồng bộ" để sử dụng cú pháp "chờ đợi" và cú pháp "chờ đợi" là cách duy nhất để thực sự chạy các chức năng không đồng bộ khác

Đây là chức năng chính của chúng tôi

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
1

Như bạn có thể thấy, chúng tôi đã khai báo nó với "async. " Sau đó, chúng tôi tạo một danh sách trống có tên là "tác vụ" để chứa các tác vụ không đồng bộ của chúng tôi [các lệnh gọi tới Genrenator và tệp I/O của chúng tôi]. Chúng tôi thêm các nhiệm vụ của mình vào danh sách của mình, nhưng chúng chưa thực sự chạy. Các cuộc gọi không thực sự được thực hiện cho đến khi chúng tôi lên lịch với

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
24. Điều này chạy tất cả các nhiệm vụ trong danh sách của chúng tôi và đợi chúng hoàn thành trước khi tiếp tục với phần còn lại của chương trình của chúng tôi. Cuối cùng, chúng tôi sử dụng
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
25 để chạy chức năng "chính" của mình. Hàm
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
26 là điểm bắt đầu cho chương trình của chúng ta và nó thường chỉ được gọi một lần cho mỗi quy trình

Đối với những người không quen thuộc,

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
27 trước các tác vụ được gọi là "giải nén đối số. " Đúng như tên gọi, nó giải nén danh sách của chúng ta thành một loạt đối số cho hàm của chúng ta. Chức năng của chúng tôi là
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
28 trong trường hợp này

Và đó là tất cả những gì chúng ta cần làm. Bây giờ, hãy chạy chương trình của chúng tôi [nguồn bao gồm chức năng định thời giống nhau của các ví dụ luồng và đồng bộ]

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
3

chúng tôi thấy nó thậm chí còn nhanh hơn. Và nói chung, phương thức asyncio sẽ luôn nhanh hơn một chút so với phương thức luồng. Điều này là do khi chúng tôi sử dụng cú pháp "chờ đợi", về cơ bản chúng tôi nói với chương trình của mình "chờ đã, tôi sẽ quay lại ngay", nhưng chương trình của chúng tôi theo dõi xem chúng tôi mất bao lâu để hoàn thành công việc đang làm. Khi chúng tôi hoàn tất, chương trình của chúng tôi sẽ biết và sẽ quay lại ngay khi có thể. Phân luồng trong Python cho phép tính không đồng bộ, nhưng về mặt lý thuyết, chương trình của chúng tôi có thể bỏ qua các luồng khác nhau có thể chưa sẵn sàng, gây lãng phí thời gian nếu có các luồng sẵn sàng tiếp tục chạy

Vậy khi nào tôi nên sử dụng luồng và khi nào tôi nên sử dụng asyncio?

Khi bạn đang viết mã mới, hãy sử dụng asyncio. Nếu bạn cần giao tiếp với các thư viện cũ hơn hoặc những thư viện không hỗ trợ asyncio, bạn có thể sử dụng luồng tốt hơn

Kiểm tra asyncio với pytest

Hóa ra việc kiểm tra các chức năng không đồng bộ với pytest cũng dễ như kiểm tra các chức năng đồng bộ. Chỉ cần cài đặt gói pytest-asyncio với

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
11, đánh dấu các bài kiểm tra của bạn bằng từ khóa
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4 và áp dụng một trình trang trí cho phép
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
41 biết nó không đồng bộ.
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
42. Hãy xem một ví dụ

Đầu tiên, hãy viết một hàm async tùy ý trong một tệp có tên hello_asyncio. py

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
2

Hàm nhận một đối số chuỗi đơn.

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
43. Khi đảm bảo rằng
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
43 là một chuỗi có độ dài lớn hơn một, chức năng của chúng tôi ngủ không đồng bộ trong hai giây, sau đó in
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
45 ra bàn điều khiển

Sự khác biệt giữa

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
46 và
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
47 là
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
46 không bị chặn

Bây giờ hãy kiểm tra nó với pytest. Trong cùng thư mục với hello_asyncio. py, tạo một tệp có tên test_hello_asyncio. py, sau đó mở nó trong trình soạn thảo văn bản yêu thích của bạn

Hãy bắt đầu với hàng nhập khẩu của chúng tôi

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4

Sau đó, chúng tôi sẽ tạo một bài kiểm tra với đầu vào thích hợp

def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    req = Request["//binaryjazz.us/wp-json/genrenator/v1/genre/", headers={"User-Agent": "Mozilla/5.0"}]
    genre = json.load[urlopen[req]]

    with open[file_name, "w"] as new_file:
        print[f"Writing '{genre}' to '{file_name}'..."]
        new_file.write[genre]
4

Những điều cần lưu ý

  • Trình trang trí
    Starting...
    Writing "college k-dubstep" to "./threading/new_file2.txt"...
    Writing "swiss dirt" to "./threading/new_file0.txt"...
    Writing "bop idol alternative" to "./threading/new_file4.txt"...
    Writing "ethertrio" to "./threading/new_file1.txt"...
    Writing "beach aust shanty français" to "./threading/new_file3.txt"...
    Time to complete threading read/writes: 0.77 seconds
    
    42 cho phép pytest hoạt động không đồng bộ
  • Thử nghiệm của chúng tôi sử dụng cú pháp
    Starting...
    Writing "college k-dubstep" to "./threading/new_file2.txt"...
    Writing "swiss dirt" to "./threading/new_file0.txt"...
    Writing "bop idol alternative" to "./threading/new_file4.txt"...
    Writing "ethertrio" to "./threading/new_file1.txt"...
    Writing "beach aust shanty français" to "./threading/new_file3.txt"...
    Time to complete threading read/writes: 0.77 seconds
    
    4
  • Chúng tôi đang
    Starting...
    Writing "college k-dubstep" to "./threading/new_file2.txt"...
    Writing "swiss dirt" to "./threading/new_file0.txt"...
    Writing "bop idol alternative" to "./threading/new_file4.txt"...
    Writing "ethertrio" to "./threading/new_file1.txt"...
    Writing "beach aust shanty français" to "./threading/new_file3.txt"...
    Time to complete threading read/writes: 0.77 seconds
    
    5ing chức năng không đồng bộ của chúng tôi như chúng tôi sẽ làm nếu chúng tôi đang chạy nó bên ngoài thử nghiệm

Bây giờ, hãy chạy thử nghiệm của chúng tôi với tùy chọn dài dòng

def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    req = Request["//binaryjazz.us/wp-json/genrenator/v1/genre/", headers={"User-Agent": "Mozilla/5.0"}]
    genre = json.load[urlopen[req]]

    with open[file_name, "w"] as new_file:
        print[f"Writing '{genre}' to '{file_name}'..."]
        new_file.write[genre]
42

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
0

có vẻ tốt. Tiếp theo, chúng ta sẽ viết một vài bài kiểm tra với đầu vào xấu. Quay lại bên trong test_hello_asyncio. py, hãy tạo một lớp có tên là

def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    req = Request["//binaryjazz.us/wp-json/genrenator/v1/genre/", headers={"User-Agent": "Mozilla/5.0"}]
    genre = json.load[urlopen[req]]

    with open[file_name, "w"] as new_file:
        print[f"Writing '{genre}' to '{file_name}'..."]
        new_file.write[genre]
43

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
1

Một lần nữa, chúng tôi trang trí các bài kiểm tra của mình bằng

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
42, đánh dấu các bài kiểm tra của chúng tôi bằng cú pháp
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4, sau đó gọi hàm của chúng tôi bằng
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5

Chạy lại các bài kiểm tra

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
2

Không có pytest-asyncio

Ngoài ra để pytest-asyncio, bạn có thể tạo một vật cố định pytest tạo ra vòng lặp sự kiện asyncio

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
3

Sau đó, thay vì sử dụng cú pháp

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5, bạn tạo các bài kiểm tra của mình như cách bạn thực hiện các bài kiểm tra đồng bộ, bình thường

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
4

Nếu bạn quan tâm, đây là hướng dẫn nâng cao hơn về thử nghiệm asyncio

Đọc thêm

Nếu bạn muốn tìm hiểu thêm về những gì phân biệt việc triển khai luồng của Python so với asyncio, thì đây là một bài viết tuyệt vời từ Medium

Để có các ví dụ và giải thích tốt hơn nữa về phân luồng trong Python, đây là video của Corey Schafer đi sâu hơn, bao gồm cả việc sử dụng thư viện

def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    req = Request["//binaryjazz.us/wp-json/genrenator/v1/genre/", headers={"User-Agent": "Mozilla/5.0"}]
    genre = json.load[urlopen[req]]

    with open[file_name, "w"] as new_file:
        print[f"Writing '{genre}' to '{file_name}'..."]
        new_file.write[genre]
49

Cuối cùng, để tìm hiểu sâu về chính asyncio, đây là một bài viết từ Real Python hoàn toàn dành riêng cho nó

Thưởng. Một thư viện khác mà bạn có thể quan tâm có tên là Unsync, đặc biệt nếu bạn muốn dễ dàng chuyển đổi mã đồng bộ hiện tại của mình thành mã không đồng bộ. Để sử dụng nó, bạn cài đặt thư viện với pip, nhập nó với

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
00, sau đó trang trí bất kỳ chức năng hiện đang đồng bộ nào với
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
01 để làm cho nó không đồng bộ. Để đợi nó và nhận giá trị trả về của nó [bạn có thể thực hiện ở bất kỳ đâu -- không nhất thiết phải ở trong hàm không đồng bộ/không đồng bộ], chỉ cần gọi
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
02 sau lệnh gọi hàm

song song là gì?

Song song có liên quan rất nhiều đến đồng thời. Trong thực tế, song song là một tập hợp con của đồng thời. trong khi một quy trình đồng thời thực hiện nhiều nhiệm vụ cùng một lúc cho dù chúng có được chuyển hướng hoàn toàn sự chú ý hay không, thì một quy trình song song thực hiện nhiều nhiệm vụ cùng một lúc. Một ví dụ điển hình là lái xe, nghe nhạc và ăn BLT mà chúng tôi đã thực hiện trong phần trước cùng một lúc

Bởi vì chúng không đòi hỏi nhiều nỗ lực, bạn có thể thực hiện tất cả chúng cùng một lúc mà không cần phải chờ đợi bất cứ điều gì hoặc chuyển hướng sự chú ý của bạn đi chỗ khác

Bây giờ hãy xem cách thực hiện điều này trong Python. Chúng ta có thể sử dụng thư viện

async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
6, nhưng thay vào đó, hãy sử dụng thư viện
def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    req = Request["//binaryjazz.us/wp-json/genrenator/v1/genre/", headers={"User-Agent": "Mozilla/5.0"}]
    genre = json.load[urlopen[req]]

    with open[file_name, "w"] as new_file:
        print[f"Writing '{genre}' to '{file_name}'..."]
        new_file.write[genre]
49 -- nó giúp loại bỏ nhu cầu quản lý số lượng quy trình theo cách thủ công. Bởi vì lợi ích chính của đa xử lý xảy ra khi bạn thực hiện nhiều tác vụ nặng bằng cpu, nên chúng tôi sẽ tính các bình phương từ 1 triệu [1000000] đến 1 triệu và 16 [1000016]

Bạn có thể tìm mã cho ví dụ này tại đây

Lần nhập duy nhất chúng tôi cần là

def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    req = Request["//binaryjazz.us/wp-json/genrenator/v1/genre/", headers={"User-Agent": "Mozilla/5.0"}]
    genre = json.load[urlopen[req]]

    with open[file_name, "w"] as new_file:
        print[f"Writing '{genre}' to '{file_name}'..."]
        new_file.write[genre]
49

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
5

Vì tôi đang phát triển trên máy Windows nên tôi đang sử dụng

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
06. Điều này là cần thiết vì Windows không có lệnh gọi hệ thống
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
07 vốn có đối với các hệ thống Unix. Bởi vì Windows không có khả năng này nên nó phải khởi chạy một trình thông dịch mới với mỗi quy trình cố gắng nhập mô-đun chính. Nếu mô-đun chính không tồn tại, nó sẽ chạy lại toàn bộ chương trình của bạn, gây ra sự hỗn loạn đệ quy xảy ra sau đó

Vì vậy, hãy xem chức năng chính của chúng tôi, chúng tôi sử dụng khả năng hiểu danh sách để tạo danh sách từ 1 triệu đến 1 triệu và 16, chúng tôi mở một ProcessPoolExecutor đồng thời. tương lai và chúng tôi sử dụng khả năng hiểu danh sách và

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
08 để bắt đầu thực hiện các quy trình của mình và đưa chúng vào một danh sách có tên là "tương lai. "

Chúng tôi cũng có thể sử dụng

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
09 nếu chúng tôi muốn sử dụng chủ đề thay thế -- concurrent. tương lai là linh hoạt

Và đây là lúc sự không đồng bộ xuất hiện. Danh sách "kết quả" không thực sự chứa kết quả từ việc chạy các chức năng của chúng tôi. Thay vào đó, nó chứa "tương lai" tương tự như ý tưởng JavaScript về "lời hứa. " Để cho phép chương trình của chúng tôi tiếp tục chạy, chúng tôi lấy lại các hợp đồng tương lai này đại diện cho một trình giữ chỗ cho một giá trị. Nếu chúng tôi cố gắng in tương lai, tùy thuộc vào việc nó có chạy xong hay không, chúng tôi sẽ nhận lại trạng thái "đang chờ xử lý" hoặc "đã hoàn thành. " Sau khi hoàn thành, chúng ta có thể nhận được giá trị trả về [giả sử có] bằng cách sử dụng

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
10. Trong trường hợp này, var của chúng ta sẽ là "result. "

Sau đó, chúng tôi lặp lại danh sách tương lai của mình, nhưng thay vì in các giá trị của chúng tôi, chúng tôi chỉ in ra "được. " Điều này chỉ là do mức độ lớn của các tính toán kết quả

Cũng như trước đây, tôi đã xây dựng một tập lệnh so sánh thực hiện điều này một cách đồng bộ. Và, như trước đây, bạn có thể tìm thấy nó trên GitHub

Chạy chương trình điều khiển của chúng tôi, cũng bao gồm chức năng định thời gian cho chương trình của chúng tôi, chúng tôi nhận được

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
6

Ồ. 54. 64 giây là một khoảng thời gian khá dài. Hãy xem liệu phiên bản đa xử lý của chúng tôi có tốt hơn không

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
7

Thời gian của chúng tôi đã được giảm đáng kể. Chúng ta đang ở khoảng 1/9 thời gian ban đầu

Vậy điều gì sẽ xảy ra nếu chúng ta sử dụng phân luồng cho việc này?

Tôi chắc rằng bạn có thể đoán được -- nó sẽ không nhanh hơn nhiều so với thực hiện đồng bộ. Trên thực tế, nó có thể chậm hơn vì vẫn mất một ít thời gian và công sức để tạo các chủ đề mới. Nhưng đừng hiểu ý tôi, đây là những gì chúng tôi nhận được khi thay thế

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
11 bằng
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
09

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
8

Như tôi đã đề cập trước đó, phân luồng cho phép các ứng dụng của bạn tập trung vào các tác vụ mới trong khi các tác vụ khác đang chờ. Trong trường hợp này, chúng tôi không bao giờ ngồi yên. Mặt khác, đa xử lý tạo ra các dịch vụ hoàn toàn mới, thường là trên các lõi CPU riêng biệt, sẵn sàng làm bất cứ điều gì bạn yêu cầu nó hoàn toàn song song với bất kỳ điều gì khác mà tập lệnh của bạn đang thực hiện. Đây là lý do tại sao phiên bản đa xử lý chiếm khoảng 1/9 thời gian có ý nghĩa - Tôi có 8 lõi trong CPU của mình

Bây giờ chúng ta đã nói về tính đồng thời và tính song song trong Python, cuối cùng chúng ta có thể thiết lập các thuật ngữ một cách thẳng thắn. Nếu bạn gặp khó khăn trong việc phân biệt giữa các thuật ngữ, bạn có thể nghĩ một cách an toàn và chính xác về các định nghĩa trước đây của chúng tôi về "song song" và "đồng thời" lần lượt là "đồng thời song song" và "đồng thời không song song"

Đọc thêm

Real Python có một bài viết tuyệt vời về đồng thời và song song

Kỹ sư Man có một video so sánh tốt về phân luồng và đa xử lý

Corey Schafer cũng có một video hay về đa xử lý theo tinh thần giống như video chia luồng của anh ấy

Nếu bạn chỉ xem một video, hãy xem bài nói chuyện tuyệt vời này của Raymond Hettinger. Anh ấy làm một công việc tuyệt vời khi giải thích sự khác biệt giữa đa xử lý, phân luồng và không đồng bộ

Kết hợp Asyncio với Đa xử lý

Điều gì xảy ra nếu tôi cần kết hợp nhiều thao tác I/O với các phép tính nặng?

Chúng ta cũng có thể làm điều đó. Giả sử bạn cần quét 100 trang web để tìm một phần thông tin cụ thể, sau đó bạn cần lưu phần thông tin đó vào một tệp để sử dụng sau. Chúng tôi có thể phân tách sức mạnh tính toán trên từng lõi của máy tính bằng cách làm cho mỗi quy trình cạo một phần trang

Đối với tập lệnh này, hãy cài đặt Beautiful Soup để giúp chúng tôi dễ dàng cạo các trang của mình.

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
13. Lần này chúng tôi thực sự có khá nhiều hàng nhập khẩu. Chúng đây rồi, và đây là lý do tại sao chúng tôi sử dụng chúng

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
9

Bạn có thể tìm mã cho ví dụ này tại đây

Đầu tiên, chúng ta sẽ tạo một hàm async gửi yêu cầu tới Wikipedia để lấy lại các trang ngẫu nhiên. Chúng tôi sẽ cạo từng trang mà chúng tôi lấy lại tiêu đề của nó bằng cách sử dụng

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
14, sau đó chúng tôi sẽ nối nó vào một tệp nhất định; . Hàm sẽ nhận hai đối số

  1. num_pages - Số trang để yêu cầu và tìm kiếm tiêu đề
  2. output_file - Tệp để nối tiêu đề của chúng tôi vào

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
90

Cả hai chúng tôi đang mở một aiohttp

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
15 không đồng bộ và tệp đầu ra của chúng tôi. Chế độ,
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
16, có nghĩa là thêm vào tệp và tạo tệp nếu nó chưa tồn tại. Mã hóa các chuỗi của chúng tôi dưới dạng utf-8 đảm bảo chúng tôi không gặp lỗi nếu tiêu đề của chúng tôi chứa các ký tự quốc tế. Nếu chúng tôi nhận được phản hồi về lỗi, chúng tôi sẽ nâng nó lên thay vì tiếp tục [với khối lượng yêu cầu cao, tôi đã nhận được 429 Quá nhiều yêu cầu]. Chúng tôi lấy văn bản từ phản hồi của mình một cách không đồng bộ, sau đó chúng tôi phân tích cú pháp tiêu đề và không đồng bộ rồi nối nó vào tệp của chúng tôi. Sau khi chúng tôi nối tất cả các tiêu đề của mình, chúng tôi nối thêm một dòng mới. "\N"

Chức năng tiếp theo của chúng tôi là chức năng chúng tôi sẽ bắt đầu với mỗi quy trình mới để cho phép chạy nó không đồng bộ

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
91

Bây giờ cho chức năng chính của chúng tôi. Hãy bắt đầu với một số hằng số [và khai báo hàm của chúng ta]

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
92

Và bây giờ logic

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
93

Chúng tôi tạo một mảng để lưu trữ tương lai của mình, sau đó chúng tôi tạo một

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
17, đặt
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
18 của nó bằng số lượng lõi của chúng tôi. Chúng tôi lặp lại một phạm vi bằng số lõi của chúng tôi trừ đi 1, chạy một quy trình mới với chức năng
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
19 của chúng tôi. Sau đó, chúng tôi nối nó vào danh sách tương lai của chúng tôi. Lõi cuối cùng của chúng tôi có khả năng sẽ có thêm việc phải làm vì nó sẽ cạo một số trang bằng với mỗi lõi khác của chúng tôi, nhưng cũng sẽ cạo thêm một số trang bằng với phần còn lại mà chúng tôi nhận được khi chia tổng số trang của mình để cạo

Đảm bảo thực sự chạy chức năng chính của bạn

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
94

Sau khi chạy chương trình với CPU 8 nhân của tôi [cùng với mã đo điểm chuẩn]

Phiên bản này [không đồng bộ với đa xử lý]

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
95

chỉ đa xử lý

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
96

chỉ không đồng bộ

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
97

Hoàn toàn đồng bộ

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
98

Tôi thực sự khá ngạc nhiên khi thấy rằng sự cải tiến của asyncio với đa xử lý thay vì chỉ đa xử lý không tốt như tôi nghĩ.

Tóm tắt lại. Khi nào nên sử dụng đa xử lý so với asyncio hoặc phân luồng

  1. Sử dụng đa xử lý khi bạn cần thực hiện nhiều phép tính nặng và bạn có thể chia nhỏ chúng ra
  2. Sử dụng asyncio hoặc phân luồng khi bạn đang thực hiện các thao tác I/O -- giao tiếp với các tài nguyên bên ngoài hoặc đọc/ghi từ/tới tệp
  3. Đa xử lý và asyncio có thể được sử dụng cùng nhau, nhưng một nguyên tắc nhỏ là rẽ nhánh một quy trình trước khi bạn xử lý/sử dụng asyncio thay vì cách khác - các luồng tương đối rẻ so với các quy trình

Không đồng bộ/Đang chờ bằng các ngôn ngữ khác

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 và cú pháp tương tự cũng tồn tại trong các ngôn ngữ khác và trong một số ngôn ngữ đó, cách triển khai có thể khác biệt đáng kể

BỌC LƯỚI. F# đến C

Ngôn ngữ lập trình đầu tiên [vào năm 2007] sử dụng cú pháp

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4 là F# của Microsoft. Trong khi nó không sử dụng chính xác
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 để chờ lệnh gọi hàm, nó sử dụng cú pháp cụ thể như
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
24 và
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
25 cùng với các hàm
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
26 độc quyền có trong mô-đun
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
27

Bạn có thể tìm hiểu thêm về lập trình async trong F# trên tài liệu F# của Microsoft

Sau đó, nhóm C# của họ đã xây dựng dựa trên khái niệm này và đó là nơi mà các từ khóa

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 mà chúng ta quen thuộc đã ra đời

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
99

chạy nó trên. NET Fiddle

Chúng tôi đảm bảo rằng chúng tôi là

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
30 vì nó bao gồm loại
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
31 và nói chung, loại
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
31 là cần thiết để chức năng không đồng bộ được chờ đợi. Điều thú vị về C# là bạn có thể làm cho chức năng chính của mình không đồng bộ chỉ bằng cách khai báo nó với
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4 và bạn sẽ không gặp vấn đề gì

Nếu bạn muốn tìm hiểu thêm về

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 trong C#, tài liệu C# của Microsoft có một trang hay về nó

JavaScript

Lần đầu tiên được giới thiệu trong ES6, cú pháp

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 về cơ bản là sự trừu tượng hóa các lời hứa JavaScript [tương tự như hợp đồng tương lai của Python]. Tuy nhiên, không giống như Python, miễn là bạn không phải chờ đợi, bạn có thể gọi một hàm async bình thường mà không cần một hàm cụ thể như Python's
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
38

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
0

Chạy nó trên JSFiddle

Xem MDN để biết thêm thông tin về

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 trong JavaScript

rỉ sét

Giờ đây, Rust cũng cho phép sử dụng cú pháp

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/_______05 và nó hoạt động tương tự như Python, C# và JavaScript

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
1

Chạy nó trên Rust Play

Để sử dụng các chức năng không đồng bộ, trước tiên chúng tôi phải thêm

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
43 vào Cargo của chúng tôi. toml. Sau đó, chúng tôi nhập chức năng
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
44 với
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
45 -
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
44 là cần thiết để chạy chức năng không đồng bộ của chúng tôi từ chức năng
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
47 đồng bộ của chúng tôi

Bạn có thể tìm thêm thông tin về

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 trong tài liệu Rust in the Rust

Đi

Thay vì cú pháp truyền thống

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 vốn có của tất cả các ngôn ngữ trước đây mà chúng ta đã đề cập, Go sử dụng "goroutines" và "channels". " Bạn có thể coi một kênh tương tự như một tương lai của Python. Trong Go, bạn thường gửi một kênh làm đối số cho một hàm, sau đó sử dụng
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
52 để chạy đồng thời hàm. Bất cứ khi nào bạn cần đảm bảo chức năng đã hoàn tất, bạn sử dụng cú pháp
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
53, bạn có thể coi đây là cú pháp
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 phổ biến hơn. Nếu goroutine của bạn [hàm bạn đang chạy không đồng bộ] có giá trị trả về, thì nó có thể được lấy theo cách này

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
2

Chạy nó trong Go Playground

Để biết thêm thông tin về đồng thời trong Go, hãy xem Giới thiệu về lập trình trong Go của Caleb Doxsey

hồng ngọc

Tương tự như Python, Ruby cũng có giới hạn Khóa thông dịch viên toàn cầu. Những gì nó không có là đồng thời được tích hợp sẵn trong ngôn ngữ. Tuy nhiên, có một loại đá quý do cộng đồng tạo ra cho phép đồng thời trong Ruby và bạn có thể tìm thấy nguồn của nó trên GitHub

Java

Giống như Ruby, Java không có cú pháp

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 tích hợp sẵn, nhưng nó có khả năng tương tranh bằng cách sử dụng mô-đun
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
57. Tuy nhiên, Electronic Arts đã viết một thư viện Async cho phép sử dụng
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 như một phương thức. Nó không hoàn toàn giống với Python/C#/JavaScript/Rust, nhưng nó đáng để xem xét nếu bạn là nhà phát triển Java và quan tâm đến loại chức năng này

C++

Mặc dù C++ cũng không có cú pháp

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5, nhưng nó có khả năng sử dụng hợp đồng tương lai để chạy mã đồng thời bằng cách sử dụng mô-đun
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
61

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
3

Chạy nó trên C++ Shell

Không cần khai báo một hàm với bất kỳ từ khóa nào để biểu thị liệu nó có thể và nên chạy không đồng bộ hay không. Thay vào đó, bạn khai báo tương lai ban đầu của mình bất cứ khi nào bạn cần với

threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
62 và đặt nó bằng
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
63, bao gồm tên của hàm bạn muốn thực hiện không đồng bộ cùng với bất kỳ đối số nào mà nó cần -- i. e. ,
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
64. Để chờ đợi giá trị của tương lai, hãy sử dụng cú pháp
threads = []

for i in range[5]:
    thread = threading.Thread[
        target=write_genre,
        args=[f"./threading/new_file{i}.txt"]
    ]
    thread.start[]
    threads.append[thread]

for thread in threads:
    thread.join[]
65 trên đó

Bạn có thể tìm tài liệu về async trong C++ trên cplusplus. com

Tóm lược

Cho dù bạn đang làm việc với mạng không đồng bộ hoặc hoạt động tệp hay bạn đang thực hiện nhiều phép tính phức tạp, có một số cách khác nhau để tối đa hóa hiệu quả mã của bạn

Nếu đang sử dụng Python, bạn có thể sử dụng

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
17 hoặc
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
6 để tận dụng tối đa hoạt động I/O hoặc mô-đun
async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
6 dành cho mã sử dụng nhiều CPU

Cũng nên nhớ rằng mô-đun

def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    req = Request["//binaryjazz.us/wp-json/genrenator/v1/genre/", headers={"User-Agent": "Mozilla/5.0"}]
    genre = json.load[urlopen[req]]

    with open[file_name, "w"] as new_file:
        print[f"Writing '{genre}' to '{file_name}'..."]
        new_file.write[genre]
49 có thể được sử dụng thay cho
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
6 hoặc
async def write_genre[file_name]:
    """
    Uses genrenator from binaryjazz.us to write a random genre to the
    name of the given file
    """

    async with aiohttp.ClientSession[] as session:
        async with session.get["//binaryjazz.us/wp-json/genrenator/v1/genre/"] as response:
            genre = await response.json[]

    async with aiofiles.open[file_name, "w"] as new_file:
        print[f'Writing "{genre}" to "{file_name}"...']
        await new_file.write[genre]
6

Nếu bạn đang sử dụng một ngôn ngữ lập trình khác, rất có thể cũng có triển khai

Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
4/
Starting...
Writing "college k-dubstep" to "./threading/new_file2.txt"...
Writing "swiss dirt" to "./threading/new_file0.txt"...
Writing "bop idol alternative" to "./threading/new_file4.txt"...
Writing "ethertrio" to "./threading/new_file1.txt"...
Writing "beach aust shanty français" to "./threading/new_file3.txt"...
Time to complete threading read/writes: 0.77 seconds
5 cho ngôn ngữ đó

Bạn muốn xem thêm các ví dụ về song song, đồng thời và không đồng bộ?

Chủ Đề