thảo luận Javascript có thực sự là single thread ?

  • Người tạo chủ đề Người tạo chủ đề teeeeeeeee
  • Ngày bắt đầu Ngày bắt đầu
thì tôi có nói setTimeOut là của JS spec đâu. Của thằng nào cũng ko quan trọng ko liên quann đến vd trên

Nhưng ý là demo cái tư tưởng bác xài cái làm j trong function truyền cho setTimeout thì cũng ko dừng đc cái loop kia.

Ví dụ của thím mình thấy liên quan đến event loop và call stack nhiều hơn, vì call stack của thím luôn ko rỗng nên cái đoạn code trong settimeout cứ ở trong queue và ko bao giờ dc đẩy sang call stack. Còn muốn chứng minh single thread ở browser thì chắc đơn giản là viết 1 cái alert và 1 đống code ở dưới cho chạy, cái alert sẽ block browser và đoạn code ở dưới chỉ chạy tiếp khi đóng cái alert, ko biết có đúng ko nhỉ :shame:
 
Ví dụ của thím mình thấy liên quan đến event loop và call stack nhiều hơn, vì call stack của thím luôn ko rỗng nên cái đoạn code trong settimeout cứ ở trong queue và ko bao giờ dc đẩy sang call stack. Còn muốn chứng minh single thread ở browser thì chắc đơn giản là viết 1 cái alert và 1 đống code ở dưới cho chạy, cái alert sẽ block browser và đoạn code ở dưới chỉ chạy tiếp khi đóng cái alert, ko biết có đúng ko nhỉ :shame:
Xét cho kỹ thì làm j có cách nào chứng minh rõ ràng đc. Vì cơ bản đâu có thực sự multithread đâu. Nên ko làm kiểu busy event loop thì còn cách nào khác?

Rõ ràng là js nó execute các event trong event loop tuần tự . Chứ model của mấy thằng khác như java có execution context. Job đc submit vô và các thread trong pool của nó lập lịch xử các job đó.



Còn cách của thím cũng có rõ ràng j đâu? Vì alert là web api



via nextVOZ for iPhone
 
https://dev.to/rajajaganathan/prove-that-javascript-runs-in-a-single-thread-1d7n
This doesn't strictly prove that JavaScript is only run on a single thread, because concurrency is very subtle.

In C++, this example (using, e.g., std::thread to start a second thread) might hang because there's no explicit synchronization of the loop variable, even though C++ can run on multiple threads

In Go, this example (using go to start a goroutines) might hang because the thread scheduler isn't fair, and might never preempt the loop without a wait in it.

Busy waiting is a bad idea in any language -- and it's why you should basically never notice that JavaScript is single threaded. The only way it should really affect your code is that you don't need mutexes/locks to protect 'critical sections' where you need to make many updates at once to be consistent
Theo bác này nói thì JS nó không có mutexes/locks nhưng vẫn đảm bảo được tính đúng/toàn vẹn của dữ liệu nên nó là Single Thead.
Cái này giống như định lý không cần chứng minh :big_smile:
 
busy wait là ví dụ không hợp lý, dù chỉ một thread nhiều ngôn ngữ nó vẫn có task scheduler để chạy nhiều task một lúc dù là một thread (google concurrent vs parallel). nếu javascript bị busy wait thì chỉ chứng tỏ được cái event loop của js kém tắm thôi :/
 
sao em chưa nghe ai bảo bao giờ nhỉ. JS nhìn nó như multithread, nhưng thật ra chỉ có đúng 1 thread thôi, trong thread đó nó có 1 luồng chính, và các luồng phụ xử lý các worker, script.... (kinh nghiệm cá nhân, các thím tay to có biết gì thì sửa giúp em :D :D)
vậy nó là đa luồng = multithread rồi còn gì nữa (chém gió bên lề tí thôi chứ mình chỉ vào đây hóng hớt tí kiến thức, mấy cái này mình cũng chưa đào sâu tìm hiểu bao giờ :D :D)
 
Lúc còn làm cho cty, cũng hay được đi phỏng vấn cùng leader. Đã pv khá nhiều ứng viên cho vị trí Js/Nodejs, hay hỏi một câu "Lấy một ví dụ để minh họa Js chạy trên môi trường trình duyệt web chrome là single thread", mới gặp được 1 cậu trả lời khá ưng, còn lại thì hơi mung lung.
Kiểu như alert phải ko thím, dù nó đc kích hoạt ở bất cứ từ thread nào (lúc này ko cần quan tâm là nó có bao nhiêu thread) nào thì js cũng đều bị block chờ user tắt cửa sổ alert để chạy tiếp => nó là single thread
 
busy wait là ví dụ không hợp lý, dù chỉ một thread nhiều ngôn ngữ nó vẫn có task scheduler để chạy nhiều task một lúc dù là một thread (google concurrent vs parallel). nếu javascript bị busy wait thì chỉ chứng tỏ được cái event loop của js kém tắm thôi :/

Giả sử task dó là CPU bound và ko ngưng luôn ( như while(true) và tính toán ko có chờ IO) thì sao thím.
Mình thấy có thằng nào làm thông minh hơn đâu. nó đều block toàn bộ cái thread đang xử lý cái task đó. JS chỉ 1 thread nên tạch, dù trong event loop còn event cần xử.
 
vậy nó là đa luồng = multithread rồi còn gì nữa (chém gió bên lề tí thôi chứ mình chỉ vào đây hóng hớt tí kiến thức, mấy cái này mình cũng chưa đào sâu tìm hiểu bao giờ :D :D)

luồng em đang nói là luồng của node, còn luồng về cpu là khác bác ơi :D

Gửi từ Điện thoại ghẻ lướt voz bằng vozFApp
 
Giả sử task dó là CPU bound và ko ngưng luôn ( như while(true) và tính toán ko có chờ IO) thì sao thím.
Mình thấy có thằng nào làm thông minh hơn đâu. nó đều block toàn bộ cái thread đang xử lý cái task đó. JS chỉ 1 thread nên tạch, dù trong event loop còn event cần xử.
làm như thế nào thì bạn có thể tham khảo tại sao OS (hoặc dễ hình dung hơn là mấy cái VPS giá rẻ) dùng một CPU vẫn chạy được đa tác vụ.

giải thích qua loa thì một chương trình đang chạy nó sẽ break thành các "chunk", nó chạy hết chunk này sẽ chạy chunk khác. tất nhiên việc đổi chunk đang chạy sang chunk khác đồng nghĩa với việc xoá hết cache nạp lại + copy data các kiểu, giảm performance đáng kể, implementation cũng phức tạp, cho nên nhiều ngôn ngữ họ thấy không cần cho nên không làm thôi.

cơ mà không phải là không có, BEAM (elarng/elixir) là một thằng tiêu biểu trong vụ tạo mấy "chunk" này cực ngắn, cho nên các bạn thường nghe nói cái BEAM này latency rất thấp, nhưng hiệu năng lại kém mấy thằng khác là vì thế. trong elixir/erlang thì dù bạn có cho chạy vòng for từ 1 tới 10^100 thì các task khác vẫn chạy bình thường, dù chỉ một CPU.
 
à mà não rút, thực ra chỉ cần ví dụ cái goroutine là được :v
hoặc mấy ngôn ngữ khác có fiber cũng tương tự :v
 
Js vẫn là single thread,
Còn webworker (browser), Worker (nodejs) để tạo thread mới chủ yếu xử lý công việc nặng nhọc
Còn bản thân js vẫn single thread, ông đúng và thằng trên cty sai
 
làm như thế nào thì bạn có thể tham khảo tại sao OS (hoặc dễ hình dung hơn là mấy cái VPS giá rẻ) dùng một CPU vẫn chạy được đa tác vụ.

giải thích qua loa thì một chương trình đang chạy nó sẽ break thành các "chunk", nó chạy hết chunk này sẽ chạy chunk khác. tất nhiên việc đổi chunk đang chạy sang chunk khác đồng nghĩa với việc xoá hết cache nạp lại + copy data các kiểu, giảm performance đáng kể, implementation cũng phức tạp, cho nên nhiều ngôn ngữ họ thấy không cần cho nên không làm thôi.

cơ mà không phải là không có, BEAM (elarng/elixir) là một thằng tiêu biểu trong vụ tạo mấy "chunk" này cực ngắn, cho nên các bạn thường nghe nói cái BEAM này latency rất thấp, nhưng hiệu năng lại kém mấy thằng khác là vì thế. trong elixir/erlang thì dù bạn có cho chạy vòng for từ 1 tới 10^100 thì các task khác vẫn chạy bình thường, dù chỉ một CPU.

ok bác, cái này thì e hiểu chỉ vì nhiều ngôn ngữ mình biết ko có implement kiểu này. Nên hỏi bác xem có thằng nào làm.
 
chả thấy liên quan gì nhau. javascript là ngôn ngữ lập trình. đa luồng/đa tiến trình là cách thực thi chương trình. nói javascript là đơn luồng sai; nói javascript là đa luồng sai nốt. nói thế khác gì bảo ngôn ngữ lập trình là cách thực thi chương trình. ông anh ở công tỹ não bò rồi.

:waaaht:
 
cái multi-threaded ở đây là người ta nói cpu thread, tức là ngôn ngữ này phải cho phép tận dụng tất cả các thread của cpu (aka có thể chạy 100% cpu), chứ đếch phải là tao dùng thêm một thread nữa chạy GC, một thread nữa chạy event loop, thế là tao cũng là multithread.

lưu ý lần nữa là cái vụ này nó phải được provide ở mức độ ngôn ngữ (runtime, stdlib etc), chứ ví dụ như ruby cái parallel gem cũng chạy theo số cores/threads được nhưng nó phải dùng marshal để giao tiếp giữa các thread thì cũng bằng nhau.

Rồi bác cho em hỏi js là multi hay single? Như bác nói thì thread chính xử lý là single:beat_brick::beat_brick::beat_brick::beat_brick:
 
Rồi bác cho em hỏi js là multi hay single? Như bác nói thì thread chính xử lý là single:beat_brick::beat_brick::beat_brick::beat_brick:
Js single thread thôi bác, cái worker nó giống kiểu tạo process khác hơn. Các dữ liệu dùng chung thì phải truyền qua lại chứ không access trực tiếp được
 
chả thấy liên quan gì nhau. javascript là ngôn ngữ lập trình. đa luồng/đa tiến trình là cách thực thi chương trình. nói javascript là đơn luồng sai; nói javascript là đa luồng sai nốt. nói thế khác gì bảo ngôn ngữ lập trình là cách thực thi chương trình. ông anh ở công tỹ não bò rồi.
Đó là lý thuyết thôi, còn thực tế thì spec và impl của lang đôi khi đi liền với nhau quan trọng là cái spec đó nó rộng đến đâu.
Ví dụ nhé:
https://docs.oracle.com/javase/specs/jls/se14/html/jls-17.html
https://en.wikipedia.org/wiki/Go_(programming_language)#Concurrency:_goroutines_and_channels
https://erlang.org/doc/reference_manual/processes.html
 
Sửa lần cuối:
Có mấy bác nói có ý đúng về việc lấy ví dụ về vụ js là single threaded.

Mấy bác lấy ví dụ sync code kiểu như: white(true), alert()... là chưa chuẩn đâu nhé, cái này thể hiện code được chạy tuần tự thôi, api alert() là hàm đồng bộ, trong ngôn ngữ Java cũng không thiếu hàm kiểu này: .readLine() (không nhớ lắm, chờ nhận một tín hiệu từ bàn phím).

Trong js bạn không thể lấy được một ví dụ mà trong đó có nhiều hơn một "luồng" cùng truy cập vào một biến. Kiểu như một "luồng" thêm dữ liệu vào mảng, "luồng" khác "pop" dữ liệu từ mảng đó ra.

Như bác này có nói, js không được impl để làm việc ở trên với tư tưởng "multi threaded"

Đó là lý thuyết thôi, còn thực tế thì spec và impl của lang đôi khi đi liền với nhau quan trọng là cái spec đó nó rộng đến đâu.
Ví dụ nhé:
https://docs.oracle.com/javase/specs/jls/se14/html/jls-17.html
https://en.wikipedia.org/wiki/Go_(programming_language)#Concurrency:_goroutines_and_channels
https://erlang.org/doc/reference_manual/processes.html


Tiện đây cũng có một câu khác, câu này được hỏi để phân cấp "trên" fresher hay không? Thật khó để ngay lập tức phân loại được một ứng viên, nhưng mình nghĩ với câu này là khá ok:

"JS là single threaded. Có 2 api để đăng nhập [1 bằng js chạy trên nodejs (express), 1 bằng Java với spring bot], người dùng sẽ gửi lên user/pass, api service truy vấn tới database để trả ra kết quả đăng nhập thành công hay không?. Database là mysql, truy vấn login luôn mất 10 phút :D. Nếu có 2 người dùng đăng nhập lần lượt đồng thời :D (liền nhau, cách nhau không đáng kể), người đăng nhập thứ 2 sẽ phải đợi bao lâu để có thể đăng nhập?", sau đó sẽ có vài câu tại sao nữa, nên bạn nào lanh lợi thì nên giải thích luôn (nếu bạn chắc chắn đoán được câu hỏi tiếp theo). Phiên phiến thôi, chính xác tới từng "phút" là được rồi.
 

Thống kê chủ đề

Ngày tạo
teeeeeeeee,
Người trả lời cuối
AnyaKyle,
Trả lời
199
Lượt xem
30.115
Quay lại
Lên đầu trang