Ý nghĩa của không đồng bộ so với đồng bộ [đóng]


46

Ý nghĩa của các từ không đồng bộđồng bộ trong khoa học máy tính là gì?

Nếu bạn google nghĩa của các từ bạn sẽ nhận được như sau:

Nhưng có vẻ như chúng được sử dụng để truyền đạt ý nghĩa ngược lại trong lập trình hoặc khoa học máy tính:

Thuộc tính async HTML có nghĩa là tập lệnh sẽ được thực thi ngay khi được tải xuống ngay cả khi HTML vẫn đang phân tích cú pháp hoặc tải xuống, có nghĩa là cả hai quá trình, tập lệnh và HTML, tồn tại và xảy ra cùng một lúc với tôi.

Là những thuật ngữ này được sử dụng để truyền đạt ý nghĩa ngược lại trong khoa học máy tính hay tôi đang thiếu điểm?


47
Tôi thấy thật dễ dàng để nói: nếu tôi không hiểu cách mã hoạt động và nếu lỗi đột nhiên biến mất khi tôi tìm kiếm chúng, mã có thể không đồng bộ. :)
Eric Duminil

4
Sự thật đáng buồn là trong lĩnh vực lập trình, theo thời gian, những từ này đã có nghĩa ngược lại với ý nghĩa của chúng. Có thể có những lý do lịch sử cho ý nghĩa hiện tại của chúng nhưng không có lời biện minh tốt.
Bí mật của Solomonoff

3
Đồng thời với những gì , là chìa khóa :)
Cuộc đua nhẹ nhàng với Monica

5
Các hoạt động thực tế không (nhất thiết) xảy ra cùng một lúc như chức năng được gọi vs hoạt động không xảy ra đồng thời các chức năng được gọi ... dường như không lạc hậu với tôi? Nếu tôi mô tả một chức năng là không đồng bộ, tôi đang nói bất cứ điều gì nó không được đảm bảo xảy ra cùng lúc với bạn gọi nó.
Ảnh hưởng

2
"Tuần tự" và "không tuần tự" có thể là những lựa chọn tốt hơn về mặt ngữ nghĩa, nhưng con tàu đó đã có cách, đã đi thuyền.
Jared Smith

Câu trả lời:


47

Tôi muốn cung cấp cho bạn một câu trả lời liên quan trực tiếp đến những định nghĩa bạn tìm thấy. Khi một tác vụ T1 bắt đầu tác vụ thứ hai T2, nó có thể xảy ra theo cách sau:

Đồng bộ: hiện có hoặc xảy ra cùng một lúc.

Vì vậy, T2 được đảm bảo để được bắt đầu và thực hiện trong lát cắt thời gian của T1 . T1 "chờ" kết thúc của T2 và có thể tiếp tục xử lý sau đó. Theo nghĩa này, T1 và T2 xảy ra "cùng một lúc" (không phải "song song", nhưng trong một khoảng thời gian tiếp giáp nhau).

Không đồng bộ: không tồn tại hoặc xảy ra cùng một lúc.

Vì vậy, thời gian thực hiện của T2 bây giờ không liên quan đến T1. Nó có thể được thực thi song song, nó có thể xảy ra một giây, một phút hoặc vài giờ sau đó và T2 vẫn có thể chạy khi T1 kết thúc (vì vậy để xử lý kết quả của T2, có thể phải thực hiện một tác vụ mới T3). Theo nghĩa này, T1 và T2 không "xảy ra cùng một lúc (khoảng thời gian)".

Tất nhiên, tôi đồng ý, các định nghĩa theo nghĩa đen dường như mơ hồ khi thấy rằng các hoạt động không đồng bộ ngày nay thường được sử dụng để tạo các thực thi song song.


4
Thật tệ khi điều này có quá nhiều sự ủng hộ, bởi vì tôi nghĩ nó không đúng. Các phương thức đồng bộ thực thi cái này ngay sau cái kia, bởi vì phương thức thứ hai phải đợi phương thức (chặn) đầu tiên hoàn thành. Hai phương thức này được quyết định không thực hiện cùng một lúc.
Robert Harvey

6
Không, tôi không nghĩ rằng tôi đã làm. Đồng bộ và đồng thời không phải là những thứ giống nhau.
Robert Harvey

1
Tôi sẵn sàng khẳng định rằng các định nghĩa từ điển không được sử dụng nhiều cho các nhà phát triển phần mềm. Cố gắng ánh xạ các định nghĩa từ điển theo các thuật ngữ kỹ thuật mà chúng tôi sử dụng có thể không hữu ích.
Robert Harvey

1
Trong mọi trường hợp, chỉnh sửa của bạn sẽ cải thiện mọi thứ, nhưng các từ "tồn tại hoặc xảy ra cùng một lúc" làm bối rối các mô tả của bạn. Các phương thức đồng bộ không thực thi "cùng một lúc;" chúng thực thi theo một trật tự , đó là những gì làm cho chúng đồng bộ.
Robert Harvey

1
@RobertHarvey Các định nghĩa từ điển hoạt động hoàn toàn tốt nếu bạn sử dụng đúng quan điểm. Bạn bị ám ảnh bởi thời gian thực hiện. Các hướng dẫn có thời gian tồn tại bên ngoài khi chúng được thực thi. Các lệnh tuần tự di chuyển đồng bộ giống như cách các viên đạn trong một khẩu súng lục ổ quay di chuyển đồng bộ. Các hướng dẫn tương tự có thể di chuyển đồng bộ thông qua các đường ống chỉ dẫn. Ngừng ám ảnh về quan điểm thực hiện. Rất nhiều chuyện tào lao xảy ra với các hướng dẫn trước khi chúng được thực thi.
candied_orange

20

Tôi thấy rằng cách tốt nhất để hiểu nó là như sau:

  • Đồng bộ: Chúng tôi biết khi nào nó sẽ xảy ra (nó xảy ra khi mã khác này kết thúc).
  • Không đồng bộ: Chúng tôi không biết khi nào nó sẽ xảy ra.

Lưu ý: mặc dù chúng ta có thể lên lịch để mã được thực thi trong một thời gian đồng hồ nhất định, nhưng thực tế chúng ta không biết khi nào nó sẽ xảy ra, bởi vì nó có thể bị trì hoãn - thậm chí bỏ qua việc gây rối với đồng hồ hệ thống - vì hệ thống đang bận làm việc khác. Ngoài ra, ngay cả khi chúng tôi có đảm bảo rằng nó sẽ xảy ra chính xác tại một thời điểm nhất định, chúng tôi không chắc chắn việc thực hiện chương trình của chúng tôi sẽ diễn ra vào thời điểm nào. Vì vậy, không, mã được lên lịch cho thời gian đồng hồ không đồng bộ.


Xin lưu ý rằng trong phát triển phần mềm, chúng tôi sẽ nói, ví dụ, một tác vụ không đồng bộ như một cái gì đó về nhiệm vụ một cách cô lập. Tuy nhiên, nếu bạn muốn xác định nó theo cách xảy ra cùng một lúc hoặc không yêu cầu phải có ít nhất một cái gì đó khác để so sánh nhiệm vụ với.

Nhiều nền tảng có thể thực hiện cả song song và chuyển đổi tác vụ, một số nền tảng bị hạn chế song song, một số không thể thực hiện song song và chỉ dựa vào chuyển đổi tác vụ ... Hơn nữa, một số nền tảng không thể làm gián đoạn một tác vụ và phải hoàn thành chúng trước khi thực hiện một nhiệm vụ khác ... Nhiệm vụ không đồng bộ là một sự trừu tượng hóa trên tất cả những thứ đó, sao cho hệ thống có thể quyết định cách chạy các tác vụ cho nền tảng nhất định mà không khiến nhà phát triển lo lắng về nó (quá nhiều).

Cũng đáng lưu ý rằng chúng ta có thể khái niệm hóa, và thông thường chúng ta trừu tượng hóa, lấy đầu vào bên ngoài như một nhiệm vụ không đồng bộ. Ví dụ: nhận văn bản từ đầu vào của người dùng. Chúng tôi không biết khi nào người dùng sẽ gõ. Điều này cũng áp dụng cho việc đọc từ bộ nhớ vĩnh viễn, nhận dữ liệu qua mạng hoặc bất kỳ hệ thống bên ngoài nào khác.


Nhân tiện, mặc dù một số thứ về cơ bản không đồng bộ, chúng ta thường có thể giả vờ rằng chúng không. Chúng tôi làm điều đó bằng cách có phần mềm chặn thực thi hiện tại - và không làm gì khác - cho đến khi hoàn thành. Đó là, chúng ta có thể lấy một cái gì đó không đồng bộ và bọc nó trong một API đồng bộ.

API không đồng bộ sẽ cho phép bạn tiếp tục thực thi mặc dù thao tác được yêu cầu chưa hoàn tất, nhưng API đồng bộ thì không. Và từ đó bạn có được ý tưởng không đồng bộ - trong phần mềm - có nghĩa là xảy ra cùng một lúc (đồng thời).

Điều đáng chú ý là không đồng bộ không bao hàm đồng thời. Trong một số trường hợp, nền tảng chỉ có thể thực thi tác vụ không đồng bộ sau khi tác vụ hiện tại đã hoàn thành. Đó sẽ là tuần tự (mặc dù thứ tự thực hiện của tác vụ không đồng bộ không nhất thiết được đảm bảo), sẽ không đồng thời (không có sự trùng lặp trong các giai đoạn thực hiện), nhưng sẽ không đồng bộ.

Ồ, nhân tiện, trong một số nền tảng, hệ thống có thể quyết định nội tuyến tác vụ không đồng bộ, và do đó thực thi nó ngay tại đó như một hoạt động đồng bộ (giả sử nó có thể, không khả thi cho mọi tác vụ).

Một lần nữa, không đồng bộ chỉ có nghĩa là bạn không biết khi nào nó sẽ xảy ra.


Bạn cũng có thể quan tâm đến sự khác biệt giữa việc thực hiện đồng thời giữa ban đầu và thời gian thực hiện song song .


Chính xác. Mô tả được tìm thấy bởi OP nghe nhiều về sự song song hơn là tính đồng bộ (nếu đó là một từ ...). asynch vs synch là về khi hành động bắt đầu (ngay bây giờ khi tôi gọi nó, hoặc sau đó khi bộ lập lịch quyết định) trong khi song song có nghĩa là "yep chúng đang xảy ra cùng một lúc" so với tuần tự.
Giacomo Alzetta

1
@GiacomoAlzetta Tôi nghĩ từ này là đồng bộ. Tôi cũng tìm thấy những từ tương tự: đồng bộ hóa, đồng bộ hóa và đồng bộ hóa. Có lẽ giá trị câu hỏi của riêng mình.
Theraot

12

Không đồng bộ: không tồn tại hoặc xảy ra cùng một lúc.

Đồng bộ: hiện có hoặc xảy ra cùng một lúc.

Thuộc tính async có nghĩa là tập lệnh sẽ được thực thi ngay khi được tải xuống ngay cả khi html vẫn đang phân tích cú pháp, điều đó có nghĩa là cả hai quá trình tồn tại cùng một lúc với tôi.

Điều này thực sự khó hiểu!

Thay vào đó hãy xem xét ý nghĩa của đồng bộ hóakhông đồng bộ . Hai thứ được đồng bộ hóa nếu thời gian của cái này phụ thuộc vào cái kia và không đồng bộ nếu thời gian của chúng không liên quan.

Trong ví dụ về quy trình làm việc không đồng bộ của bạn, chúng tôi có hai điều xảy ra: thực thi tập lệnh và phân tích cú pháp html. Hai điều này không đồng bộ ; thời gian của hoạt động thực thi và thời gian của hoạt động phân tích cú pháp không phụ thuộc lẫn nhau. Nếu chúng tôi thực hiện quy trình làm việc đồng bộ , thì các hoạt động sẽ trở nên đồng bộ . Nói, việc thực thi không bắt đầu cho đến khi phân tích cú pháp chắc chắn đã kết thúc.

Nhưng điều quan trọng là phải nhận ra rằng thực sự có ba khả năng ở đây:

  • thực thi và phân tích cú pháp thực sự không đồng bộ; chúng có thể xảy ra bất cứ lúc nào và theo bất kỳ thứ tự nào, bất cứ điều gì hiệu quả nhất.
  • thực thi và phân tích cú pháp được đồng bộ hóa; nói, CPU không làm trong khi chờ I / O hoàn thành.
  • thực thi và phân tích cú pháp được đồng bộ hóa, nhưng trong khi chúng tôi chờ I / O hoàn thành, CPU được phép thực hiện các công việc khác, sau đó quay lại và thực hiện phân tích cú pháp sau khi quá trình tải xuống hoàn tất .

Khi bạn nắm bắt được điều đó, mục đích của quy trình làm việc không đồng bộ trong các ngôn ngữ lập trình phổ biến sẽ trở nên rõ ràng hơn:

  • Quy trình làm việc không đồng bộ giúp chúng tôi triển khai các hoạt động có độ trễ cao một cách hiệu quả vì chúng tôi không bị hạn chế để đặt hàng những thứ không liên quan kịp thời. Nếu phân tích cú pháp có độ trễ cao và ràng buộc I / O và thực thi tập lệnh có độ trễ cao và CPU bị ràng buộc, chúng ta có thể giành chiến thắng bằng cách không đồng bộ hóa hoàn toàn hoặc một phần các hoạt động đó.

  • Các awaitnhà điều hành trong các ngôn ngữ như C # là hoạt động đặt hàng trên quy trình công việc không đồng bộ. Một chờ đợi là một chờ đợi không đồng bộ ; nó là một điểm mà chúng tôi thể hiện một mối quan hệ đặt hàng giữa hai phần của một công việc không đồng bộ, và nói rằng có một "xảy ra trước khi" mối quan hệ giữa các mã trước khi chờ đợi và mã sau khi chờ đợi. Đây là cách chúng tôi thực hiện tùy chọn thứ ba .

Nếu đó là tất cả quá trừu tượng, hãy nghĩ về một số ví dụ thực tế. Khi bạn gửi thư - một hoạt động ràng buộc I / O có độ trễ cao - bạn vẫn có thể thực hiện công việc đòi hỏi nhiều CPU - bài tập về nhà toán học - trong khi bạn đang chờ để nhận được thư trả lời. Các hoạt động làm bài tập toán và đọc thư của bạn không đồng bộ.

Nhưng giả sử bây giờ bạn gửi thư và thư trả lời có chứa một số bạn cần để làm thuế. Bây giờ bạn không thể làm CPU hoạt động - tính thuế của bạn - cho đến khi hoàn thành thao tác I / O. Nhưng bạn vẫn có thể cắt cỏ trong khi chờ đợi . Đó là một quy trình làm việc không đồng bộ đã thể hiện mối quan hệ thời gian giữa các bộ phận của nó.


6

Tôi là một kỹ sư điện và chúng tôi đã xử lý đồng bộ và không đồng bộ trong các mạch logic (cổng logic).

Giả sử bạn có cổng AND (hoặc bất kỳ cổng nào), có hai đầu vào và đầu ra.

Nếu nó không đồng bộ, nó sẽ cập nhật đầu ra vào thời điểm bất kỳ đầu vào nào thay đổi theo cách mà đầu ra thay đổi. Đây là cách ví dụ của bạn hoạt động - chương trình bạn đã đề cập.

Tuy nhiên, nếu cổng đó cũng có đồng hồ (ví dụ: sóng vuông 1 giây) được gắn vào nó, nơi nó cập nhật theo nhịp của mỗi giây, vì sóng vuông đi từ thấp đến cao, nó đồng bộ. Nó bị ràng buộc với tần số của đồng hồ. Vì vậy, nó là đồng bộ. Bạn có thể nối đồng hồ đó với nhiều mạch và chúng sẽ hoạt động nhịp nhàng với nhau - được đồng bộ hóa. Nếu chương trình của bạn chỉ kiểm tra xem nó đã được đọc để chạy mỗi giây hay chưa, thì nó cũng sẽ được đồng bộ hóa.


1
Giống như cổng nối tiếp không đồng bộ / đồng bộ.
jiwopene

2

Hãy tưởng tượng hai vệ tinh quay quanh Trái đất.

  • Vệ tinh A có chu kỳ quay quanh Trái đất sao cho mỗi lần quay toàn bộ hành tinh, vệ tinh đã đi vòng quanh Trái đất nhiều hơn một lần .
  • Vệ tinh B có chu kỳ quay quanh Trái đất sao cho mỗi lần quay toàn bộ hành tinh, vệ tinh đã đi vòng quanh Trái đất đúng một lần .

Vệ tinh B trong ví dụ trên nằm trong quỹ đạo không đồng bộ theo định nghĩa của

có thời gian quay đồng bộ với thời gian quay của trái đất.

Người ta không tranh luận rằng vệ tinh A là không đồng bộ địa lý đơn giản chỉ vì nó "tồn tại hoặc xảy ra cùng một lúc" với hành tinh. Trên thực tế, bản thân vệ tinh B cũng không phải là điều có liên quan - điều có liên quan là thời kỳ quay được đồng bộ hóa với thời kỳ quay với thời gian của Trái đất. Nó không phải là về sự tồn tại đồng thời của các đối tượng; đó là về mối quan hệ giữa các đối tượng. Giữ ý nghĩ này.

Giả sử tôi nói với bạn hai luồng trên một hệ thống đang chạy cùng một lúc. Chủ đề A (TA) đang tìm nạp dữ liệu cho Quy trình A và Chủ đề B (TB) đang tìm nạp dữ liệu cho Quy trình B. Tôi hỏi bạn: "TA và TB có đồng bộ không?". Câu trả lời của bạn sẽ là "Làm sao tôi biết được? Id phải xem mã đã gọi chúng trong các quy trình tương ứng của chúng." Tôi đã cố gắng để cố gắng trở nên khó khăn, "Nhưng tôi đang nói với bạn rằng TA và TB chắc chắn đang chạy cùng một lúc."

Khi anh em đã hoàn toàn cá nhân thông minh, sẽ trả lời, "Một lần nữa - họ có thể chạy đồng thời nhưng tôi không có đầu mối nếu họ đang chạy không đồng bộ liên quan đến các quá trình của mình mà gọi họ TA và TB chạy không đồng bộ để. Nhau thực sự làm không có ý nghĩa gì vì chúng không sinh ra từ cùng một quá trình. "

Vì vậy, bây giờ chúng ta nên có được một số trực giác rằng sự tồn tại của một mối quan hệ là những gì có liên quan ở đây, không chỉ là sự tồn tại của hai chủ đề này. Khi một phương thức được thực thi không đồng bộ, điều chúng ta đang nói là việc thực thi phương thức đó " KHÔNG cần tồn tại hoặc xảy ra cùng một lúc" như việc thực thi phương thức đã gọi nó. Lấy ví dụ sau:

func Invoker() {
    DoThis();
    DoThatAsync();

    var foo = CheckThis();
    ... do some work ...
    CheckThat(foo);

    await DoThatAsync();

    CheckThat();
}

Từ cuộc thảo luận của chúng tôi về các vệ tinh trước đó, "Không phải là về sự tồn tại đồng thời của các vật thể, mà là về mối quan hệ giữa các vật thể." Nó không phải là về sự tồn tại của một phương thức gọi và phương thức được gọi; đó là về sự tồn tại của một mối quan hệ giữa việc thực hiện kẻ xâm lược và việc thực hiện người được viện dẫn. Nếu chúng tôi xem xét các luồng hệ thống của chúng tôi và thấy rằng nó DoThatAsync()được gọi nhưng không thực thi, có thể nó đang chờ trên lịch trình hoặc một số I / O khác, điều đó không nhất thiết có nghĩa là phương thức gọi Invoker()không thực thi - có thể nó hoạt động được đang làm. Chắc chắn, nó có thể ở điểm awaiting DoThatAsync(), nhưng điều đó không được đảm bảo. Điều này không đúng với các chức năng khác khi chúng được gọi - nếu chúng dừng lại,Invoker()dừng lại - không có vấn đề gì Điều này được đảm bảo. Việc thực thi giữa Invoker()phương thức đồng bộ và được gọi "tồn tại hoặc xảy ra cùng một lúc".


Tôi thực sự thích điều này. Nói chung, đó là miền tây hoang dã của việc thực thi tùy ý là "không đồng bộ" so với đường dẫn thực thi rõ ràng được xác định là "đồng bộ"
Cruncher

Tôi cũng nghĩ rằng đây là câu trả lời tốt nhất.
Barmar

2

Ví dụ cụ thể

Tôi muốn thêm một số ví dụ trong thế giới thực và kết nối chúng với thế giới công nghệ phần mềm. Trước tiên, hãy xem xét một cái gì đó mà tôi hy vọng phù hợp với định nghĩa trực quan của bạn về "đồng bộ": nhấp nháy của đom đóm , trong một số trường hợp. Thứ hai, hãy xem xét cuộc đua tiếp sức Olympic 4x100 của phụ nữ . Thứ ba, hãy xem xét trope cũ từ các bộ phim quân sự: "Đàn ông, đồng bộ hóa đồng hồ của bạn!"

Bây giờ, hãy nghĩ về những gì đang xảy ra. Hãy bắt đầu bằng cách quan sát rằng tất cả những điều này là các quá trình hoặc các thực thể được kéo dài theo thời gian . Thật vô nghĩa khi nói rằng một cái bát là "đồng bộ" và rock là "không đồng bộ". Thứ hai, phải mất hai đến tango . Bạn không thể nói rằng "một người chạy là đồng bộ hóa". Đồng bộ hóa với cái gì? Cuối cùng, để hai quá trình thực hiện cùng một lúc, trừ khi chúng có cùng tần số và pha chính xác, một hoặc cả hai quá trình phải chờ .

Phân tích

Khi định nghĩa từ điển nói rằng hai thực thể đồng bộ "xảy ra hoặc tồn tại cùng một lúc", điều đó rất phù hợp với khái niệm ánh sáng từ đom đóm. Thật không may, nói rằng ánh sáng là "đồng bộ" là một cách cẩu thả để nói rằng các quy trình chiếu sáng đom đóm được đồng bộ hóa.

Vậy làm thế nào để một đàn đom đóm, có lẽ không có Apple SmartWatch và NTP để hướng dẫn chúng, quản lý để nháy đèn hậu của chúng cùng một lúc? Chà, thật dễ dàng nếu họ có một phương tiện để đặt nhịp độ nhất quán và có thể thực hiện những điều chỉnh nhỏ cho nó. Chúng chỉ flash, và nếu nhiều người hơn flash ngay sau chúng, chúng sẽ chậm lại (tăng độ trễ), trong khi nếu nhiều flash hơn ngay trước chúng, chúng sẽ tăng tốc (giảm độ trễ). Vì vậy, họ có thể sử dụng một quá trình phản hồi đơn giản để đến cơ bản cùng một nhịp độ và giai đoạn. Quan sát quan trọng ở đây là lưu ý rằng họ đạt được sự đồng bộ bằng cách chờ đợi thời điểm thích hợp để flash .

Cuộc đua 4x100 rất thú vị bởi vì bạn thấy cả hai hình thức xử lý thời gian hoạt động: các vận động viên trong một nhóm được đồng bộ hóa, trong khi các vận động viên trên các đội khác nhau là " không đồng bộ ". Người chạy thứ hai trong rơle phải đợi cho đến khi người chạy thứ nhất vào khu vực chuyển nhượng . Việc bắt tay là một sự kiện đồng bộ giữa hai vận động viên đó. Tuy nhiên, những người chạy ở các làn đường khác nhau không quan tâm đến những gì đang xảy ra ở một làn đường khác , và chắc chắn là không làm chậm và thực hiện đồng bộ hóa tay của họ. Mỗi làn của người chạy là không đồng bộ với nhau. Một lần nữa, chúng ta thấy rằng đồng bộ hóa đòi hỏi phải chờ đợi, trong khi không đồng bộ hóa thì không.

Cuối cùng, những người lính trong một đại đội (trung đội, đội cứu hỏa, v.v.) phải đồng bộ hóa đồng hồ của họ để có thể tấn công kẻ thù cùng một lúc . Nó có thể là một số binh sĩ đến vị trí của họ trước những người khác, hoặc có cơ hội bắn vào kẻ thù sớm hơn. Nhưng một cuộc tấn công đồng thời thường hiệu quả hơn một cuộc tấn công ngớ ngẩn vì yếu tố bất ngờ. Vì vậy, để đạt được sự đồng bộ, nhiều người lính phải chờ thời gian chỉ định để hành động.

Xác định tính năng

Tại sao điều này nhấn mạnh vào sự chờ đợi? Vâng, đó là bởi vì chờ đợi là tính năng xác định phân biệt đồng bộ với các quy trình không đồng bộ. Nếu bạn có hai quy trình mà bạn không biết gì về nó, theo mặc định, bạn nên cho rằng chúng không đồng bộ. Ví dụ: giao hàng trọn gói và lái xe cứu thương rất có thể không được đồng bộ hóa. Trên thực tế, để chứng minh rằng hai quá trình được đồng bộ hóa, bạn cần tìm một thời điểm rất đặc biệt: thời điểm đồng bộ hóa .

Một tài xế giao hàng thả gói hàng và xe cứu thương đưa ai đó đến bệnh viện thường không chia sẻ bất kỳ điểm nào mà chúng tôi xác định là "điểm đồng bộ hóa". Mặt khác, những con đom đóm nhấp nháy đồng loạt có một điểm đồng bộ mỗi khi chúng nhấp nháy, những người chạy tiếp sức có một điểm đồng bộ mỗi khi họ cầm dùi cui và binh lính có một điểm đồng bộ khi họ phát động cuộc tấn công. Nếu bạn có thể xác định một hoặc nhiều điểm đồng bộ hóa, thì các quy trình được đồng bộ hóa . Điều này nên dễ hiểu, bởi vì "syn-" là tiền tố Hy Lạp có nghĩa là "với" hoặc "cùng nhau" và "chrono" là từ gốc Hy Lạp cho "thời gian". "Đồng bộ hóa" nghĩa đen là "cùng một lúc",

Ranh giới

Lưu ý rằng "đồng bộ hóa" không nhất thiết phải áp dụng cho toàn bộ vòng đời của một hoặc cả hai quá trình. Tôi sẽ lập luận rằng nó chỉ áp dụng cho "thời gian chờ lên đến và bao gồm (các) điểm đồng bộ hóa". Do đó, hai quy trình có thể hoạt động không đồng bộ cho đến khi chúng đạt đến trạng thái cần liên lạc, sau đó chúng được đồng bộ hóa, trao đổi thông tin và sau đó tiếp tục không đồng bộ. Một ví dụ đơn giản là gặp ai đó để uống cà phê. Rõ ràng, cuộc họp là một điểm đồng bộ hóa (hoặc nhiều hơn, đúng hơn), và thực tế là hai người đến điểm đó thể hiện sự đồng bộ. Tuy nhiên, chúng tôi sẽ không nói rằng vì hai người gặp nhau vì cà phê, hai kiếp người đóđược "đồng bộ hóa". Có thể đó là khoảnh khắc duy nhất trong cuộc sống của họ mà họ gặp, và mọi thứ khác họ làm đều độc lập.

Nó cũng không phải là trường hợp ngẫu nhiên đáp ứng chứng minh sự đồng bộ. Nếu hai người lạ gặp nhau trên đường phố, thực tế là họ đang ở một nơi cụ thể vào một lúc nào đó không chứng minh được sự đồng bộ. Thực tế là một người đang ngồi trên băng ghế chờ xe buýt, và một người khác tình cờ đi ngang qua. Các quy trình chỉ đồng bộ khi chúng đáp ứng cho một mục đích .

Kết nối phần mềm

Bây giờ, hãy nghĩ về một nhiệm vụ rất cơ bản trong phần mềm: đọc từ một tệp. Như bạn có thể biết, lưu trữ dung lượng lớn thường chậm hơn hàng nghìn đến hàng triệu lần so với bộ nhớ cache hoặc bộ nhớ chính. Vì lý do này, các hệ điều hành và thư viện ngôn ngữ lập trình thường cung cấp cả hoạt động I / O đồng bộ và không đồng bộ. Bây giờ, ngay cả khi chương trình của bạn chỉ có một luồng duy nhất, bạn nên nghĩ HĐH là một "quy trình riêng" cho mục đích thảo luận này.

Đồng bộ hóa

Khi bạn thực hiện "đọc I / O đồng bộ", luồng của bạn phải đợi cho đến khi dữ liệu có sẵn, tại thời điểm đó nó tiếp tục. Điều này rất giống với một vận động viên chạy tiếp sức đưa cây dùi cui cho người chạy tiếp theo, nhưng hãy tưởng tượng thay vào đó là một cuộc tiếp sức chỉ có hai vận động viên chạy suốt đường đua, và người chạy thứ hai cũng quay lại với người đầu tiên.

Trong trường hợp này, luồng chương trình của bạn và quá trình I / O của hệ điều hành không "xảy ra (diễn ra) cùng một lúc", và do đó có vẻ kỳ lạ khi nói rằng các quy trình này được "đồng bộ hóa". Nhưng đó là cách nhìn sai lầm! Điều đó giống như nói: "Các vận động viên trong nhóm chuyển tiếp không chạy cùng một lúc, vì vậy họ không được đồng bộ hóa." Trong thực tế, cả hai tuyên bố đều sai! Các vận động viên trong một nhóm tiếp sức làmphải chạy cùng một lúc, nhưng chỉ tại một thời điểm rất cụ thể: việc tắt dùi cui. Trên thực tế, chỉ có khoảnh khắc đặc biệt này trong cuộc đua mới thuyết phục chúng tôi rằng các đội tiếp sức được đồng bộ hóa để bắt đầu! Nếu chúng tôi xem yêu cầu và phản hồi I / O là "dùi cui",

Mặt khác, nếu chúng ta nghĩ về một cái gì đó như Phân tích phần tử hữu hạn trên siêu máy tính, chúng ta thấy rằng hàng ngàn quy trình phải hoạt động theo từng bước để cập nhật trạng thái toàn cầu lớn. Ngay cả khi một số nút hoàn thành công việc của họ trong một bước thời gian nhất định trước các nút khác, tất cả chúng đều cần đợi bước thời gian hoàn thành vì kết quả lan truyền đến hàng xóm qua không gian. Kiểu đồng bộ này giống như những con đom đóm: tất cả các diễn viên đều thực hiện cùng một loại nhiệm vụ.

Quy trình đa dạng

Vì lý do này, chúng tôi có thể phát minh ra một số thuật ngữ để giúp chúng tôi thấy rằng có ba loại điều đang diễn ra: "đồng bộ đồng nhất", "đồng bộ không đồng nhất" và "đồng bộ tuần tự". Vì vậy, khi các diễn viên đang thực hiện cùng một nhiệm vụ đồng thời (FEA, đom đóm), họ "đồng nhất". Khi họ đang thực hiện các nhiệm vụ khác nhau cùng một lúc (những người lính chạy so với bò so với bơi đến đích của họ, vật lý so với âm thanh so với chủ đề AI trong một trò chơi), họ "không đồng nhất". Khi họ đang thực hiện từng nhiệm vụ một, chúng là "tuần tự" (người chạy tiếp sức, chặn I / O). Chúng có thể trông rất khác nhau, nhưng chúng có chung một thuộc tính thiết yếu: tất cả các loại diễn viên thực hiện một số chờ đợi để đảm bảo rằng tất cả mọi người đến điểm đồng bộ hóa cùng một lúc. ở giữa các điểm đồng bộ hóa, hoặc "thực hiện cùng một hành động" không liên quan đến tính đồng bộ.

Các đường ống kết xuất trong GPU là đồng bộ vì tất cả chúng phải hoàn thành khung cùng nhau và bắt đầu một khung mới cùng nhau. Họ đồng nhất bởi vì họ đang làm cùng một loại công việc, và tất cả họ đều hoạt động cùng nhau. Nhưng vòng lặp trò chơi chính của máy chủ và các luồng I / O chặn xử lý đầu vào từ xa không đồng nhất vì chúng thực hiện các loại công việc rất khác nhau và một số luồng I / O sẽ không làm gì cả, vì không phải tất cả các kết nối được sử dụng. Mặc dù vậy, chúng được đồng bộ hóa, bởi vì chúng phải chia sẻ trạng thái nguyên tử (người chơi không được xem cập nhật thế giới trò chơi một phần, và máy chủ cũng không chỉ thấy một đoạn đầu vào của người chơi).

Không đồng bộ

Bây giờ, chúng ta hãy xem xét một "đọc I / O không đồng bộ". Khi chương trình của bạn gửi yêu cầu đến HĐH để đọc một chút dữ liệu từ bộ lưu trữ, cuộc gọi sẽ trả về ngay lập tức . Hãy bỏ qua các cuộc gọi lại và tập trung vào bỏ phiếu. Nói chung, thời điểm dữ liệu có sẵn cho chương trình của bạn không tương ứng với bất kỳ thời điểm đặc biệt nào liên quan đến chủ đề chương trình của bạn. Nếu chương trình của bạn không chờ đợi dữ liệu một cách rõ ràng, thì luồng sẽ không biết chính xác thời điểm đó xảy ra. Nó sẽ chỉ phát hiện ra rằng dữ liệu đang chờ trong lần kiểm tra tiếp theo.

Không có thời gian họp đặc biệt khi HĐH và luồng chương trình đồng ý bàn giao dữ liệu. Họ giống như hai con tàu đi qua trong đêm. Không đồng bộ được đặc trưng bởi sự vắng mặt của sự chờ đợi này. Tất nhiên, chuỗi chương trình thường sẽ kết thúc chờ đợi trên hoạt động I / O, nhưng nó không cần. Nó có thể vui vẻ tiếp tục thực hiện các tính toán khác trong khi quá trình tìm nạp I / O đang diễn ra và chỉ kiểm tra sau khi có thời gian rảnh. Tất nhiên, một khi HĐH đã tải xong dữ liệu, nó cũng không phải chờ đợi. Nó chỉ đặt dữ liệu ở đâu đó thuận tiện và tiếp tục công việc của mình. Trong trường hợp này, nó giống như chương trình trao dùi cui cho HĐH và HĐH xuất hiện sau đó, thả dùi cui xuống đất cùng với dữ liệu và rời khỏi đường đua. Chương trình có thể hoặc không thể chờ đợi để nhận được thông báo.

Song song

Khi chúng tôi đánh dấu một chức năng là "không đồng bộ" trong phần mềm, điều đó thường có nghĩa là chúng tôi muốn song song . Nhưng hãy nhớ rằng song song không ngụ ý đồng bộ . Những con đom đóm là một ví dụ tốt, bởi vì chúng, cũng thể hiện cả hành vi đồng bộ và không đồng bộ. Trong khi hầu hết những con ruồi đồng loạt lóe lên, nhiều con rõ ràng đã không đồng điệu với phần còn lại của nhóm và lóe lên một cách ngẫu nhiên hơn. Những con ruồi có thể đã hành động đồng thời , nhưng chúng không được đồng bộ hóa .

Bây giờ khi chúng tôi đánh dấu một số mã là "async", nó trông buồn cười, bởi vì nó ngụ ý rằng phần còn lại của mã không được đánh dấu là "đồng bộ hóa". Điều đó có nghĩa là gì? Không phải chúng tôi đã nhấn mạnh rằng "đồng bộ hóa" cần hai đến tango sao? Nhưng nếu chúng ta đang nói về việc thực thi mã trong một luồng thì sao? Trong trường hợp này, chúng ta cần lùi lại một bước và suy nghĩ về một chương trình như một chuỗi các trạng thái và chuyển tiếp giữa các trạng thái đó. Một tuyên bố trong một chương trình gây ra sự chuyển đổi trạng thái. Chúng ta có thể nghĩ về nó như là một "quy trình vi mô" bắt đầu và dừng lại với tuyên bố. Trên thực tế, các điểm trình tự được xác định bởi ngôn ngữ là các điểm đồng bộ hóa của các "quy trình vi mô" này. Và do đó, chúng ta có thể xem một luồng đơn,

Tính toàn vẹn của ngôn ngữ lập trình đảm bảo rằng các cập nhật trạng thái không can thiệp vào các câu lệnh và các điểm trình tự xác định các ranh giới mà trình biên dịch không được phép thực hiện tối ưu hóa có thể quan sát được. Ví dụ, thứ tự đánh giá các biểu thức trong một câu lệnh có thể không được xác định hoặc không được xác định rõ, cho phép trình biên dịch tự do tối ưu hóa câu lệnh theo nhiều cách khác nhau. Nhưng vào thời điểm câu lệnh tiếp theo bắt đầu, chương trình sẽ ở trạng thái được xác định rõ, nếu bản thân PL là âm thanh.

Đến bây giờ, rõ ràng chúng ta muốn nói gì về "async". Điều đó có nghĩa chính xác là hợp đồng đồng bộ ngụ ý trong một khối mã được miễn cho khối async. Nó được phép cập nhật trạng thái chương trình một cách độc lập, không có sự đảm bảo về an toàn thường được ngụ ý bởi mô hình tính toán tuần tự (nhất quán, đồng bộ). Tất nhiên, điều này có nghĩa là chúng ta cần phải đặc biệt quan tâm rằng chúng ta không phá hủy trạng thái chương trình một cách không nhất quán. Điều này thường có nghĩa là chúng tôi giới thiệu đồng bộ rõ ràng , hạn chế để phối hợp với khối async. Lưu ý rằng điều này có nghĩa là khối async có thể không đồng bộ đồng bộ tại các thời điểm khác nhau! Nhưng nhắc lại rằng đồng bộ hóa chỉ đơn thuần cho thấy sự tồn tại của điểm đồng bộ hóa, chúng ta sẽ không gặp khó khăn khi chấp nhận khái niệm này.


Bạn có thể xóa tất cả các ví dụ của mình ở đây ngoại trừ cuộc đua tiếp sức (minh họa rõ ràng các khái niệm phần mềm về đồng bộ và không đồng bộ, trong khi các ví dụ khác thì không), và câu trả lời của bạn sẽ cải thiện đáng kể.
Robert Harvey

Tôi nghĩ rằng các ví dụ khác thể hiện hành động đồng thời so với hành động không đồng nhất, điều mà tôi tin rằng đã gây ra nhiều nhầm lẫn của OP.
Người cắt cỏ

1

Một cách để nghĩ về nó là hướng dẫn SIMD , như AVX . Dưới đây là một số ví dụ về cách chúng được sử dụng.

Các hướng dẫn SIMD đồng bộ cho phép bạn thực hiện nhiều phép tính cùng một lúc , trong cùng một luồng, bằng cách vận hành một Lệnh đơn trên nhiều dữ liệu.

Trong khi đa luồng không đồng bộ cho phép bạn thực hiện nhiều phép tính tại thời điểm "có thể" "hơi" "tương tự".

Kết hợp điều này với các định nghĩa sau:

tính từ đồng bộ syn · chro · nous | \ ˈSiŋ-krə-nəs, ˈsin-

1: xảy ra, tồn tại hoặc phát sinh cùng một lúc [nhấn mạnh của tôi]

tính từ không đồng bộ asyn · chro · nous | \ (ˌ) ā-ˈsiŋ-krə-nəs, -ˈsin- \

1: [...]: không đồng bộ


1

Một sự tương tự làm cho tôi hiểu sự khác biệt giữa Sync vs Async so với Multi-threaded là của một đầu bếp trong bếp.

Hãy tưởng tượng bạn đang làm mì ống. Bạn có ba bước:

  1. Luộc và làm khô mì ống
  2. Chuẩn bị nước sốt
  3. Kết hợp mì ống và nước sốt

Phương pháp đồng bộ. Trong kịch bản đồng bộ, chỉ có một người (luồng) thực hiện tất cả các công việc theo trình tự. Đầu tiên bạn luộc mì ống và bạn đứng đó nhìn nó sôi. Sau đó, bạn thoát nước và đặt nó sang một bên. Sau đó bạn chuẩn bị nước sốt. Khi nước sốt đã sẵn sàng, bạn lấy mì ống, trộn nó với nước sốt và món ăn của bạn đã sẵn sàng. Vấn đề ở đây là nó không hiệu quả. Bởi vì bạn đã làm việc tuần tự một cách đồng bộ, bạn không thể làm việc với nước sốt trong khi mì ống đang sôi. Vì vậy, nó làm bạn lãng phí thời gian, và mì ống của bạn bị lạnh trong khi nước sốt đang được chuẩn bị.

Phương pháp không đồng bộ. Trong kịch bản này, vẫn chỉ có một đầu bếp (sợi), nhưng trong khi mì ống đang sôi bạn đi và làm nước sốt của bạn. Khi mì ống được đun sôi, bạn đang called-backlàm nước sốt để ráo nước, và sau đó bạn called-backlại hoàn thành nước sốt. Điều này hiệu quả hơn bây giờ, vì bạn đã tiết kiệm thời gian và mì ống của bạn không phải đợi nước sốt lâu như vậy.

Phương pháp đa luồng. Bây giờ, hãy tưởng tượng bạn thuê một đầu bếp mới. Bây giờ bạn có hai đầu bếp (chủ đề). Trong khi một đầu bếp đang làm mì ống, đầu bếp thứ hai đang làm nước sốt. Có cần thiết trong kịch bản này? Không, bởi vì làm mì ống đủ đơn giản để hiệu quả với phương pháp không đồng bộ. Và, quản lý nhiều đầu bếp là chi phí bổ sung. Nhưng nếu bạn đang làm món ăn phức tạp hơn hoặc nhiều món ăn cùng một lúc, nhiều đầu bếp sẽ hữu ích.


Đây thực sự là một sự tương tự khá tốt.
Robert Harvey

0

Một câu hỏi hay và các thuật ngữ thường được sử dụng theo những cách khác nhau dẫn đến nhầm lẫn.

Câu trả lời của tôi là các thuật ngữ này là tương đối - và những gì chúng có liên quan là chương trình chính đang thực thi (hoặc đôi khi với một luồng).

Các thuật ngữ này xác định điều gì đó về hoạt động và thời gian nội bộ của chương trình, như liệu tin nhắn được gửi hoặc nhận theo cách chặn (đồng bộ hóa) hay theo cách không chặn (không đồng bộ). Nếu một luồng (chính) bị chặn bằng cách gửi hoặc nhận, đó là "đồng bộ hóa" và nếu nó bị gián đoạn bằng cách nào đó thì đó là "không đồng bộ". Để nhắc lại, các điều khoản này là về các triển khai mà cả hai thực hiện (thường xuyên) cũng như xử lý các sự kiện.

(IMHO, tất nhiên) một khi có tin nhắn trên mạng, không có thứ gì như đồng bộ hóa với async. Trong nhắn tin có một người gửi và người nhận, mỗi người trong số họ có thể có một triển khai đồng bộ hóa hoặc không đồng bộ độc lập với nhau - nhưng một khi tin nhắn được kết nối, nó chỉ là một tin nhắn, không còn đồng bộ hóa hoặc không đồng bộ. Chúng tôi có thể phân loại tin nhắn là yêu cầu hoặc trả lời hoặc tin nhắn một chiều, nhưng đó là trực giao để đồng bộ hóa và không đồng bộ (đề cập đến việc triển khai đang chặn chờ hay có thể bị gián đoạn theo một cách nào đó).


Không chặn khác với không đồng bộ,
user207421

1
@ user207421 vui lòng giải thích, vì tôi sẽ gọi chúng là từ đồng nghĩa trong ngữ cảnh này
Jacob Raihle

0

"đồng bộ" có nghĩa rằng hai sự kiện xảy ra cùng một lúc - nhưng các sự kiện?

Khi chúng tôi nói "thực thi đồng bộ", chúng tôi có nghĩa là người gọi và callee đang thực thi (tức là trên ngăn xếp) cùng một lúc. Đó có lẽ là ý nghĩa của bạn sau.

Khi chúng ta nói "cổng logic đồng bộ", có nghĩa là cổng logic được đồng bộ hóa với đồng hồ cpu.

Khi chúng tôi nói "mô hình đồng bộ" trong ngữ cảnh của các hệ thống phân tán, chúng tôi có nghĩa là tất cả các nút thực hiện chương trình của họ ở bước khóa và các tin nhắn được gửi ở bước n được đảm bảo đến đầu bước n + 1.

Khi Đặc tả ngôn ngữ Java nói rằng một luồng "đồng bộ hóa" với một luồng khác, điều đó có nghĩa là các hành động trong các luồng khác nhau xảy ra "cùng một lúc" (liên quan đến xảy ra trước khi quan hệ). Và khi họ nói rằng hai luồng "đồng bộ hóa truy cập vào một đối tượng", họ thực sự có nghĩa là các luồng đồng bộ hóa với nhau để đảm bảo chúng không bao giờ hoạt động trên đối tượng cùng một lúc.

... Và tôi khá chắc chắn rằng bạn có thể áp dụng từ này trong nhiều ngữ cảnh hơn nữa, bởi vì "mọi thứ xảy ra cùng một lúc" là một ý tưởng khá chung chung :-)


0

Tôi nghĩ rằng chìa khóa của sự nhầm lẫn của bạn có thể được tóm tắt bằng cách:

Thuộc tính async có nghĩa là tập lệnh sẽ được thực thi ngay khi được tải xuống ngay cả khi html vẫn đang phân tích cú pháp

Điều cần nhận ra là câu này không có ý nghĩa vì nó mô tả một tình huống không thể. Nếu HTML vẫn phân tích cú pháp thì quá trình tải xuống tập lệnh thậm chí sẽ không bắt đầu nếu nó không đồng bộ.

Trong lập trình, phương tiện đồng bộ:

Tất cả dữ liệu bạn quan tâm đã tồn tại trong bộ nhớ tại thời điểm bạn thực hiện logic của mình

Trong khi phương tiện không đồng bộ:

Một số dữ liệu bạn quan tâm chưa tồn tại và chỉ tồn tại ở một thời điểm nào đó trong tương lai

Thật vậy, chính khía cạnh không phải là hiện tại của lập trình không đồng bộ này thường khiến mọi người bối rối.

Làm thế nào các tập lệnh được tải bình thường là phân tích cú pháp html bị tạm dừng, sau đó tập lệnh được tải xuống, khi quá trình tải xuống tập lệnh hoàn thành, nó được thực thi và sau đó quá trình phân tích cú pháp html tiếp tục. Việc phân tích cú pháp html và thực thi tập lệnh xảy ra tại cùng một thời điểm (cùng thời gian có nghĩa với nhau, không đồng thời).

Làm thế nào asynccác tập lệnh được tải là html nhìn thấy thẻ script và sau đó ghi nhớ để tải xuống tập lệnh trong tương lai nhưng tiếp tục phân tích cú pháp. Phân tích cú pháp html không bị tạm dừng để tải xuống tập lệnh. Sau đó , sau khi phân tích cú pháp html hoàn tất, tất cả các tập lệnh async được tải xuống và thực thi. Việc phân tích cú pháp và thực thi tập lệnh html không xảy ra cùng một lúc (một lần nữa, cùng một lúc có nghĩa là cùng nhau, trong trường hợp này chúng được thực hiện riêng).

Vì vậy, để tóm tắt:

  • Các tập lệnh đồng bộ được phân tích cú pháp cùng với html.

  • Các kịch bản không đồng bộ được phân tích cú pháp riêng trong tương lai.

Vì vậy, định nghĩa của thuộc asynctính không phải là tập lệnh được thực thi ngay khi được tải xuống - điều này đúng cho cả tập lệnh đồng bộ và không đồng bộ. Định nghĩa của async là phân tích cú pháp html không chờ tập lệnh tải xuống .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.