Javascript là đa luồng hoặc đơn luồng

Bạn đã đọc nhiều bài báo để cố gắng hiểu liệu Node. js là đơn luồng hay đa luồng? . Trong bài viết này, tôi hy vọng sẽ làm sáng tỏ sự nhầm lẫn này

Theo Nút. js, một Node. ứng dụng js chạy bằng vòng lặp sự kiện. Vòng lặp sự kiện là thứ cho phép Node. js để thực hiện các hoạt động I/O không bị chặn và giải thích cách Node. js có thể không đồng bộ. Vòng lặp sự kiện, hay còn gọi là luồng chính, cho phép chạy từng thứ một. Đã nói rằng, Node. js mã JavaScript chạy trên một luồng duy nhất

Bây giờ, có một số điểm mà bạn có thể đã đọc trong các bài viết khác nhau, chẳng hạn như sử dụng worker_threads làm cho nó đa luồng hoặc ngôn ngữ lập trình được sử dụng để phát triển Node. ứng dụng js làm cho nó đơn luồng, v.v. Tôi sẽ đề cập đến những điểm liên quan đó, nhưng trước khi chúng ta tiếp tục, tôi sẽ làm mới kiến ​​thức của bạn về quy trình đơn và đa luồng là gì

Mục lục

  • Quy trình đơn luồng là gì
  • Quy trình đa luồng là gì
  • Tại sao nút. js là Đơn luồng?
  • Không chặn Vòng lặp sự kiện [còn gọi là Chủ đề chính]
  • JavaScript và Node khó hiểu. Quy trình xử lý luồng js
  • Điều gì về chủ đề công nhân trong nút. js? . js Đa luồng?

Quy trình đơn luồng là gì

Một quy trình đơn luồng là việc thực hiện các hướng dẫn được lập trình theo một trình tự duy nhất. Phải nói rằng, nếu một ứng dụng có bộ hướng dẫn sau

  • Hướng dẫn A
  • Hướng dẫn B
  • Hướng dẫn C

Nếu tập hợp các hướng dẫn này được thực thi trong một quy trình đơn luồng, quá trình thực thi sẽ giống như sau

Trở thành một lập trình viên giỏi hơn

@bblập trình viên

Bạn có biết #nodejs là Đơn luồng hay Đa luồng không? . //t. co/hEXzX0avGA #becomeabetterprogrammer #nodejsdevelopers #javascriptdeveloper #javascript

Javascript vốn không phải là ngôn ngữ đơn luồng hoặc đa luồng. Có những môi trường Javsacript không cung cấp luồng Javascript và môi trường cung cấp luồng Javascript. Bản thân ngôn ngữ không chỉ định tính đơn luồng hoặc đa luồng. Thay vào đó, môi trường có muốn cung cấp các luồng Javascript hay không là tùy thuộc vào môi trường.

Vì vậy, với câu hỏi cụ thể của bạn

JavaScript có đơn luồng không?

Không. Nó không cụ thể là một luồng hoặc nhiều luồng. Đặc tả ngôn ngữ cũng không yêu cầu. Phân luồng của Javascript tùy thuộc vào môi trường thời gian chạy để triển khai. Điều đó xảy ra là cả trình duyệt và nút. js bắt đầu không có luồng Javascript và kiến ​​trúc hướng sự kiện dẫn đến quan niệm rằng không có luồng nào trong môi trường Javascript, nhưng CÓ. Hiện cả hai đều cung cấp các luồng Javascript [Công nhân web trong trình duyệt và Worker_Threads trong nút. js]

Đặc tả Javascript cung cấp một số tính năng hữu ích trong môi trường đa luồng, chẳng hạn như các đối tượng SharedArrayBuffer và Atomics và các môi trường cung cấp luồng cung cấp các thư viện bổ sung. Vì vậy, đặc tả ngôn ngữ hiện tại nhận ra một số nhu cầu của đa luồng và cung cấp một số công cụ cho nó, mặc dù không có yêu cầu cụ thể nào về việc thời gian chạy Javascript có hoặc không có luồng. Tùy thuộc vào thời gian chạy liệu họ có muốn cung cấp khả năng đó để chạy song song nhiều luồng thực thi Javascript hay không

JavaScript là ngôn ngữ được giải thích, không phải là ngôn ngữ được biên dịch. Điều này có nghĩa là nó cần một trình thông dịch để chuyển đổi mã JS thành mã máy. Có một số loại trình thông dịch [được gọi là động cơ]. Các công cụ trình duyệt phổ biến nhất là V8 [Chrome], Quantum [Firefox] và WebKit [Safari]. Ngẫu nhiên, V8 cũng được sử dụng trong thời gian chạy không có trình duyệt phổ biến, Node. js

Mỗi công cụ chứa một đống bộ nhớ, ngăn xếp cuộc gọi, vòng lặp sự kiện, hàng đợi gọi lại và API Web với các yêu cầu HTTP, bộ hẹn giờ, sự kiện, v.v. , tất cả được thực hiện theo cách riêng của nó để diễn giải mã JS nhanh hơn và an toàn hơn

Kiến trúc thời gian chạy JS cơ bản. Tác giả. Alex Zlatkov

chủ đề duy nhất

Ngôn ngữ đơn luồng là ngôn ngữ có một ngăn xếp cuộc gọi và một đống bộ nhớ. Nó có nghĩa là nó chỉ chạy một thứ tại một thời điểm

stack là một vùng bộ nhớ liên tục, phân bổ ngữ cảnh cục bộ cho từng chức năng được thực thi

heap là một vùng lớn hơn nhiều, lưu trữ mọi thứ được phân bổ động

call stack là một cấu trúc dữ liệu về cơ bản ghi lại vị trí của chúng ta trong chương trình

ngăn xếp cuộc gọi

Hãy viết một mã đơn giản và theo dõi những gì đang xảy ra trên ngăn xếp cuộc gọi

Như bạn có thể thấy, các chức năng được thêm vào ngăn xếp, được thực hiện và sau đó bị xóa. Đó là cái gọi là cách LIFO - Nhập sau, Xuất trước. Mỗi mục nhập trong ngăn xếp cuộc gọi được gọi là một stack frame

Kiến thức về ngăn xếp cuộc gọi rất hữu ích để đọc dấu vết ngăn xếp lỗi. Nói chung, lý do chính xác của lỗi nằm ở trên cùng trong dòng đầu tiên, mặc dù thứ tự thực thi mã là từ dưới lên

Đôi khi, bạn có thể xử lý một lỗi phổ biến, được thông báo bởi Maximum call stack size exceeded. Thật dễ dàng để có được điều này bằng cách sử dụng đệ quy

function foo[] {
    foo[]
}
foo[]

và trình duyệt hoặc thiết bị đầu cuối của chúng tôi bị treo. Mỗi trình duyệt, ngay cả các phiên bản khác nhau của chúng, có giới hạn kích thước ngăn xếp cuộc gọi khác nhau. Trong phần lớn các trường hợp, chúng là đủ và vấn đề nên được tìm kiếm ở nơi khác

Ngăn xếp cuộc gọi bị chặn

Đây là một ví dụ về việc chặn luồng JS. Hãy thử đọc một tệp foo và một bar bằng Node. chức năng đồng bộ js_______8

Đây là một GIF lặp lại. Như bạn thấy, công cụ JS đợi cho đến khi cuộc gọi đầu tiên trong readFileSync hoàn thành. Nhưng điều này sẽ không xảy ra vì không có tệp foo, vì vậy hàm thứ hai sẽ không bao giờ được gọi

Hành vi không đồng bộ

Tuy nhiên, JS cũng có thể không bị chặn và hoạt động như thể nó là đa luồng. Điều đó có nghĩa là nó không đợi phản hồi của lệnh gọi API, sự kiện I/O, v.v. và có thể tiếp tục thực thi mã. Có thể nhờ vào các công cụ JS sử dụng [dưới mui xe] các ngôn ngữ đa luồng thực, như C++ [Chrome] hoặc Rust [Firefox]. Họ cung cấp cho chúng tôi API Web dưới trình duyệt hoặc ví dụ. API I/O dưới Nút. js

Trong ảnh GIF ở trên, chúng ta có thể thấy rằng hàm đầu tiên được đẩy vào ngăn xếp lệnh gọi và stack1 được thực thi ngay lập tức trong bảng điều khiển

Sau đó, chúng tôi gọi hàm stack2 do WebAPI của trình duyệt cung cấp. Nó chuyển đến ngăn xếp cuộc gọi và chức năng gọi lại không đồng bộ foo của nó chuyển đến hàng đợi của WebApi, nơi nó chờ cuộc gọi, được đặt để diễn ra sau 3 giây

Trong thời gian chờ đợi, chương trình tiếp tục viết mã và chúng tôi thấy stack4 trong bảng điều khiển

Sau khi được gọi, mỗi chức năng trong hàng đợi API Web sẽ chuyển đến ________ 15. Đó là nơi các chức năng đợi cho đến khi ngăn xếp cuộc gọi trống. Khi nó xảy ra, họ được chuyển đến đó từng người một

Vì vậy, khi bộ đếm thời gian stack2 của chúng tôi kết thúc đếm ngược, chức năng foo của chúng tôi sẽ chuyển đến hàng đợi gọi lại, đợi cho đến khi ngăn xếp cuộc gọi khả dụng, chuyển đến đó, được thực thi và chúng tôi thấy stack8 trong bảng điều khiển

Câu hỏi đặt ra là, làm thế nào để bộ thực thi biết rằng ngăn xếp cuộc gọi trống và làm thế nào sự kiện trong hàng đợi gọi lại được gọi? . Nó là một phần của công cụ JS. Quá trình này liên tục kiểm tra xem ngăn xếp cuộc gọi có trống không và nếu có, theo dõi xem có sự kiện nào trong hàng đợi gọi lại đang chờ được gọi hay không

Đó là tất cả sự kỳ diệu đằng sau hậu trường

Kết thúc lý thuyết

Đồng thời và song song

stack9 có nghĩa là thực hiện nhiều nhiệm vụ cùng lúc nhưng không đồng thời. e. g. hai nhiệm vụ hoạt động trong khoảng thời gian chồng chéo

heap0 có nghĩa là thực hiện đồng thời hai hoặc nhiều nhiệm vụ, e. g. thực hiện nhiều phép tính cùng một lúc

Chủ đề & Quy trình

heap1 là một chuỗi thực thi mã có thể được thực thi độc lập với nhau

heap2 là phiên bản của một chương trình đang chạy. Một chương trình có thể có nhiều tiến trình

Đồng bộ & Không đồng bộ

Trong heap3 lập trình, các tác vụ được thực hiện lần lượt. Mỗi tác vụ đợi bất kỳ tác vụ nào trước đó được hoàn thành và chỉ được thực hiện sau đó

Trong heap4 lập trình, khi một tác vụ được thực thi, bạn có thể chuyển sang một tác vụ khác mà không cần đợi tác vụ trước hoàn thành

Đồng bộ và không đồng bộ trong môi trường đơn và đa luồng

heap5. Các nhiệm vụ được thực hiện lần lượt. Mỗi tác vụ chờ tác vụ trước đó được thực thi

heap6. Các tác vụ được thực thi trong các luồng khác nhau nhưng đợi mọi tác vụ đang thực thi khác trên bất kỳ luồng nào khác

heap7. Các tác vụ bắt đầu được thực thi mà không cần đợi một tác vụ khác kết thúc. Tại một thời điểm nhất định, chỉ có thể thực hiện một tác vụ duy nhất

heap8. Các tác vụ được thực thi trong các luồng khác nhau mà không cần đợi các tác vụ khác hoàn thành và hoàn thành việc thực thi của chúng một cách độc lập

Nếu chúng tôi xem xét cách thức hoạt động của các công cụ JS, chúng tôi có thể phân loại JS là ngôn ngữ diễn giải không đồng bộ và đơn luồng. Từ "được giải thích" rất quan trọng vì nó có nghĩa là ngôn ngữ sẽ luôn phụ thuộc vào thời gian chạy và không bao giờ nhanh bằng các ngôn ngữ được biên dịch với đa luồng tích hợp

Đáng chú ý là nút. js có thể đạt được đa luồng thực sự, miễn là mỗi luồng được bắt đầu như một quy trình riêng biệt. Có thư viện cho việc này, nhưng Node. js có một tính năng tích hợp có tên là Worker Threads

Tất cả ảnh GIF vòng lặp sự kiện đều đến từ ứng dụng Loupe do Philip Roberts tạo, nơi bạn có thể kiểm tra các tình huống không đồng bộ của mình

JavaScript có thể là đa

Nhờ những tiến bộ gần đây trong ngôn ngữ--chẳng hạn như các đối tượng Atomics và SharedArrayBuffers cũng như Web Worker trong trình duyệt-- JavaScript hiện là ngôn ngữ đa luồng. These features will go down as being the biggest paradigm shift for the world's most popular programming language.

Tại sao JavaScript chỉ có một luồng?

Javascript là một luồng vì bạn không thể có 2 bộ mã liên tiếp chạy xen kẽ hoặc đồng thời trên nhiều lõi . JavaScript hỗ trợ các kỹ thuật lập trình không đồng bộ có thể xuất hiện đa luồng, nhưng nó chỉ chia mã thành các đoạn được thực thi bởi một luồng đơn lẻ.

JavaScript có đồng bộ và đơn luồng không?

JavaScript là ngôn ngữ lập trình đơn luồng , không chặn, không đồng bộ, đồng thời với nhiều tính linh hoạt. Đợi một chút - nó có nói đơn luồng và không đồng bộ cùng một lúc không? .

Chủ Đề