JavaScript neden çoklu okuma özelliğini desteklemiyor?


269

Kasıtlı bir tasarım kararı mı yoksa gelecek sürümlerde düzeltilecek mevcut tarayıcılarımızla ilgili bir sorun mu?


3
Web çalışanları / çalışan konuları hakkında bilgi için JavaScript ve Konular sorununun yanıtlarına da bakın .
Sam Hasler

115
Merhaba, Google çalışanı. Burada her şeyin oldukça tarihli göründüğünü fark edebilirsiniz (bu sorunun 5 yıl önce sorulduğunu unutmayın.) Sorulduğundan beri, web tarayıcıları, anlayabildiğim kadarıyla, az ya da çok iş parçacığı olan bazı yetenekler kazanmıştır. Web Çalışanlarına bir göz atın: msdn.microsoft.com/en-us/hh549259.aspx
ArtOfWarfare

2
Multithread.js, Web Çalışanlarını sarar ve JS'de kolay çoklu kullanım sağlar. İOS Safari de dahil olmak üzere tüm yeni tarayıcılarda çalışır. :)
kwh

Yanıtlar:


194

Tarayıcıdaki JavaScript yorumlayıcısı tek bir iş parçacığı (AFAIK) olduğu için JavaScript çoklu iş parçacığını desteklemiyor. Google Chrome bile tek bir web sayfasının JavaScript'inin aynı anda çalışmasına izin vermez, çünkü bu mevcut web sayfalarında büyük eşzamanlılık sorunlarına neden olur. Tüm Chrome'un yaptığı ayrı işlemler, birden çok bileşeni (farklı sekmeler, eklentiler, vb.) Ayrı işlemlere ayırmaktır, ancak birden fazla JavaScript iş parçacığına sahip tek bir sayfa düşünemiyorum.

Bununla birlikte, önerildiği gibi, setTimeoutbir tür programlama ve “sahte” eşzamanlılığa izin vermek için kullanabilirsiniz . Bu, tarayıcının oluşturma iş parçacığının denetimini yeniden ele geçirmesine setTimeoutve verilen milisaniyeden sonra verilen JavaScript kodunu başlatmasına neden olur . Bu, üzerinde işlem yaparken görünümün (gördüklerinizin) yenilenmesine izin vermek istiyorsanız çok kullanışlıdır. Sadece koordinatlar arasında geçiş yapmak ve bir elemanı buna göre güncellemek sadece başlangıç ​​ve bitiş konumlarını görmenizi sağlar ve aradaki hiçbir şeyi görmez.

JavaScript'te, hepsi aynı JavaScript yorumlayıcısı tarafından yönetilen işlemler ve iş parçacıkları oluşturmamızı sağlayan bir soyutlama kitaplığı kullanıyoruz. Bu, eylemleri aşağıdaki şekilde yürütmemizi sağlar:

  • Proses A, Diş 1
  • Proses A, Diş 2
  • Proses B, Diş 1
  • Proses A, Diş 3
  • Proses A, Diş 4
  • Proses B, Diş 2
  • İşlemi Duraklat A
  • Proses B, Diş 3
  • Proses B, Diş 4
  • Proses B, Diş 5
  • İşlem A'yı başlat
  • Proses A, Diş 5

Bu, bir tür zamanlamaya ve paralelliğe, ipliklerin başlatılmasına ve durdurulmasına vb. İzin verir, ancak gerçek çoklu iş parçacığı olmayacaktır. Gerçek dil iş parçacığının yalnızca tarayıcı tek iş parçacıklı çok iş parçacıklı (veya birden fazla çekirdeği) çalıştırabildiği ve çok daha büyük zorlukları olduğu için dilin kendisinde uygulanacağını düşünmüyorum ekstra olasılıklardan daha fazla.

JavaScript'in geleceği için şu adrese göz atın: https://developer.mozilla.org/presentations/xtech2006/javascript/


73
Bence hiç uygulanmayan bir görüş çok dar. Web uygulamalarının sonunda gerçekten çok iş parçacıklı olabileceğini garanti ediyorum (web uygulamaları daha baskın hale geldiğinden ve donanım daha paralel hale geldiğinden sadece mantıklıdır) ve gördüğüm gibi, JavaScript web geliştirmenin fiili dili olduğundan, eninde sonunda çoklu iş parçacığını desteklemesi ya da yerine başka bir şey gelmesi gerekecektir.
devios1

6
Asla muhtemelen çok cesur bir açıklama biraz :) ama yine de gerçek çok iş parçacıklı javascript avantajlarının öngörülebilir gelecekte mümkün olmadığını düşünüyorum;)
Kamiel Wanrooij

5
Her ne kadar web çalışanlarının bir süreç modeli aracılığıyla bir iplik modelinden daha eşzamanlı olduklarını iddia etsem de. Web çalışanları mesaj geçişini, çok iş parçacıklı uygulamalarda 'olağan' eşzamanlılık sorunlarına zarif bir çözüm olan iletişim aracı olarak kullanırlar. Aynı anda ana sayfa ile aynı nesneler üzerinde çalışıp çalışamayacağından emin değilim. Bildiğim kadarıyla DOM'ye erişemiyorlar. Bununla birlikte, bunların çoğu anlambilimdir, web çalışanları tüm niyet ve amaçlar için umut verici görünürler.
Kamiel Wanrooij

Ekstra olasılıklardan çok daha büyük zorluklar var . Tüm ekstra olasılıkları düşündüğünüzden emin değilim. Özellikle webgl'in oyunlarda veya grafiksel görselleştirmelerde kullanıldığı durumları düşünüyorum. Örneğin, Google Haritalar'ın yeni 3D sürümünü düşünün. Birçok 3D modeli olan şehirlerde, bilgisayarımın birçok evin işlenmesi gerektiğinde her şeyi yüklemek için ~ 2 dakikaya ihtiyacı var. Belirli açılardan ne grafik kartım ne de ağım kapasiteye çalışmıyor. Ancak 8 işlemciden biri% 100'dür. Bu örnekte gösterildiği gibi, multithreading de fps açısından büyük bir endişe kaynağı: youtube.com/watch?v=sJ2p982cZFc
Scindix

25

JavaScript çoklu iş parçacığı (bazı sınırlamalarla) burada. Google, Gears için çalışanları uyguladı ve çalışanlar HTML5'e dahil edildi. Çoğu tarayıcı bu özellik için zaten destek ekledi.

İşçiye / çalışandan iletilen tüm veriler serileştirildiği / kopyalandığı için verilerin iş parçacığı güvenliği garanti edilir.

Daha fazla bilgi için okuyun:

http://www.whatwg.org/specs/web-workers/current-work/

http://ejohn.org/blog/web-workers/


8
Ancak çok iş parçacıklı olmaktan ziyade çok işlemli yaklaşım değil midir? İş parçacıklarının tek bir yığın içinde çalıştığı bilinmektedir.
beefeather

1
@beefeather, bu doğru. Bu daha çok bir süreç yaklaşımıdır.
Neil

23

Geleneksel olarak, JS kısa, hızlı çalışan kod parçaları için tasarlanmıştır. Büyük hesaplamalar yapıyorsanız, bunu bir sunucuda yaptınız - tarayıcınızda uzun süre çalışan bir JS + HTML uygulaması fikri önemsiz şeyler yapmak saçma oldu.

Tabii ki, şimdi buna sahibiz. Ancak, tarayıcıların yakalaması biraz zaman alacak - çoğu tek iş parçacıklı bir model etrafında tasarlandı ve değiştirmek kolay değil. Google Gears, arka planda yürütmenin izole edilmesini gerektirerek birçok potansiyel sorunu yan adımlara yönlendirir - DOM'yi değiştirmez (iş parçacığı için güvenli olmadığı için), ana iş parçacığı (ditto) tarafından oluşturulan erişilen nesneler yoktur. Kısıtlayıcı olmakla birlikte, bu, hem tarayıcının tasarımını basitleştirdiği hem de deneyimsiz JS kodlayıcılarının iş parçacıkları ile uğraşmasına izin verme riskini azalttığı için yakın gelecekte en pratik tasarım olacaktır ...

@marcio :

Neden Javascript'te çoklu iş parçacığı uygulamak için bir neden? Programcılar sahip oldukları araçlar ile istediklerini yapabilirler.

Öyleyse, onlara açtığım diğer tüm web sitelerinin tarayıcımı çökmesine neden olacak şekilde kötüye kullanımı kolay araçlar vermeyelim . Bunun naif bir uygulaması sizi doğrudan IE7 gelişimi sırasında MS'e çok fazla baş ağrısına neden olan bölgeye getirecektir: eklenti yazarları, iplik geçirme modeliyle hızlı ve gevşek oynadılar, bu da birincil iplik üzerinde nesne yaşam döngüleri değiştiğinde ortaya çıkan gizli hatalarla sonuçlandı . KÖTÜ. IE için çok iş parçacıklı ActiveX eklentileri yazıyorsanız, sanırım bölge ile birlikte gelir; bundan daha ileri gitmesi gerektiği anlamına gelmez.


6
"deneyimsiz JS kodlayıcılar> iş parçacıkları ile karışıklık izin verme riskini azaltır" Neden Javascript çoklu iş parçacığı uygulamak için bir nedeni bu? Programcılar sahip oldukları araçlar ile istediklerini yapabilirler. İyi ya da kötü ise, bu onların sorunu. Google Chrome işlem modeliyle diğer uygulamaları bile etkileyemez. :)
Marcio Aguiar

3
@ Shog9 - "Açtığım diğer tüm web sitelerinin tarayıcımı çökmesine neden olacak şekilde kötüye kullanımı çok kolay olan [programcılar] araçları vermeyelim." - Ne? Aynı mantıkla, hiçbir dilde birden çok iş parçacığı bulunmamalıdır, çünkü eğer açmaya çalıştığınız diğer tüm programların çökeceğini söylediler. Ancak bu şekilde çalışmaz. Diş çekme çoğu dilde mevcuttur ve çoğu acemi programcı buna dokunmaz ve üretime girmeyenlerin çoğu ve asla popüler veya yaygın olarak kullanılmayan uygulamalar.
ArtOfWarfare

11

Bu kararın mantığını bilmiyorum, ancak setTimeout kullanarak çok iş parçacıklı programlamanın bazı avantajlarını simüle edebileceğinizi biliyorum. Gerçekte her şey tek bir iş parçacığında gerçekleşse de, aynı anda bir şeyler yaparak birden çok işlem yanılsamasını verebilirsiniz.

Sadece işlevinizin biraz iş yapmasını sağlayın ve sonra şöyle bir şey çağırın:

setTimeout(function () {
    ... do the rest of the work...
}, 0);

Ve yapılması gereken diğer şeyler (UI güncellemeleri, animasyonlu resimler vb.) Bir şans elde ettiklerinde gerçekleşir.


Çoğu durumda bir loopiç kullanmak istiyorum , setTimeoutama görünüşe göre bu işe yaramaz. Böyle bir şey yaptın mı yoksa bir hackin var mı? bir örnek 1000 eleman dizisi için olurdu, ben setTimeoutilk aramalar üzerinden ve baskı elemanı 0..499, ikinci döngüler üzerinden ve baskı elemanı olacak şekilde iki çağrı içinde döngüler için iki kullanmayı umuyoruz 500..999.
benjaminz

Genellikle teknik, durumu kurtarmak ve devam etmektir. Örneğin, 0 ile 1000 arasında yazdırmak istediğinizi varsayalım, 0 ile 499 arasında yazdırabilir ve daha sonra 500 bağımsız değişkeniyle setTimeout hile yapabilirsiniz.
Eyal

8

Yani dil neden çoklu okumayı desteklemiyor veya tarayıcılardaki JavaScript motorları neden çoklu okumayı desteklemiyor?

İlk sorunun cevabı, tarayıcıdaki JavaScript'in bir sanal alanda ve makineden / işletim sisteminden bağımsız bir şekilde çalıştırılması, çoklu iş parçacığı desteği eklemenin dili karmaşıklaştıracağı ve dili işletim sistemine çok yakın bağlayacağıdır.


6

Node.js 10.5+, çalışan iş parçacıklarını deneysel özellik olarak destekler ( --exorimental-worker bayrağı etkinken kullanabilirsiniz): https://nodejs.org/api/worker_threads.html

Yani, kural:

  • G / Ç bağlı ops yapmanız gerekiyorsa , dahili mekanizmayı kullanın (aka geri arama / söz / asenkron-await)
  • CPU bağlı ops yapmanız gerekiyorsa , işçi iş parçacıklarını kullanın.

Çalışan iş parçacıklarının uzun ömürlü iş parçacıkları olması amaçlanmıştır, yani bir arka plan iş parçacığı oluşturursunuz ve daha sonra onunla mesaj ileterek iletişim kurarsınız.

Aksi takdirde, anonim bir işlevle ağır bir CPU yükü yürütmeniz gerekiyorsa , çalışan iş parçacıklarının etrafında inşa edilmiş küçük bir kütüphane olan https://github.com/wilk/microjob ile gidebilirsiniz .


4

Matt b'nin dediği gibi, soru çok açık değil. Dilde çoklu iş parçacığı desteği istediğini varsayarsak: şu anda tarayıcıda çalışan uygulamaların% 99,999'u için gerekli olmadığından. Gerçekten ihtiyacınız varsa, geçici çözümler vardır (window.setTimeout kullanmak gibi).

Genel olarak çoklu iş parçacığı, ekstra kısıtlamalar koymadığınız sürece (sadece değişmez veriler kullanmak gibi) doğru olmak için çok, çok, çok, çok, çok, çok zor (zor olduğunu mu söyledim?).


3

Intel, Javascript'te çok iş parçacığına ilişkin bazı açık kaynaklı araştırmalar yapıyor, son zamanlarda GDC 2012'de sergilendi. İşte video için link . Araştırma grubunda öncelikle Intel Chip setleri ve Windows işletim sistemine odaklanan OpenCL kullanılmıştır. Proje kod adı RiverTrail'dir ve kod GitHub'da kullanılabilir

Bazı yararlı bağlantılar:

Web Uygulamaları için Bilgi İşlem Yolu Oluşturma



1

Çoklu diş açmayı desteklemeyen uygulamalar. Şu anda Google Gears, harici işlemleri yürüterek bir tür eşzamanlılık kullanmanın bir yolunu sunuyor, ancak hepsi bu.

Google'ın bugün yayınlaması beklenen yeni tarayıcı (Google Chrome), devam etmekte olan bazı kodları paralel olarak yürütmektedir.

Temel dil, elbette, Java ile aynı desteğe sahip olabilir, ancak Erlang'ın eşzamanlılığı gibi bir şey için destek ufukta hiçbir yerde değildir.


1

Javascript tek iş parçacıklı bir dildir. Bu, bir çağrı yığını ve bir bellek yığını olduğu anlamına gelir. Beklendiği gibi, kodu sırayla yürütür ve bir sonrakine geçmeden önce bir parça kodunu yürütmeyi bitirmelidir. Eşzamanlı, ancak zaman zaman zararlı olabilir. Örneğin, bir işlevin yürütülmesi biraz zaman alırsa veya bir şeyi beklemek zorunda kalırsa, bu arada her şeyi dondurur.


0

Duyduğum kadarıyla Google Chrome'un çok iş parçacıklı javascript'i olacak, bu yüzden "mevcut uygulamalar" sorunu.


0

İş parçacığı senkronizasyonu için uygun dil desteği olmadan, yeni uygulamaların denenmesi bile mantıklı değildir. Mevcut karmaşık JS uygulamaları (örneğin, ExtJS kullanan herhangi bir şey) büyük olasılıkla beklenmedik bir şekilde kilitlenir, ancak bir synchronizedanahtar kelime veya benzer bir şey olmadan , doğru davranan yeni programlar yazmak da çok zor hatta imkansız olabilir.


-1

Ancak, bazı işlevleri eşzamanlılık getirmek için eval işlevini kullanabilirsiniz.

/* content of the threads to be run */
var threads = [
        [
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');"
        ],
        [
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');"
        ]
    ];

window.onload = function() {
    var lines = 0, quantum = 3, max = 0;

    /* get the longer thread length */
    for(var i=0; i<threads.length; i++) {
        if(max < threads[i].length) {
            max = threads[i].length;
        }
    }

    /* execute them */
    while(lines < max) {
        for(var i=0; i<threads.length; i++) {
            for(var j = lines; j < threads[i].length && j < (lines + quantum); j++) {
                eval(threads[i][j]);
            }
        }
        lines += quantum;
    }
}

-2

Javascript ile çoklu iş parçacıkları HTML5 tarafından getirilen web işçileri kullanılarak açıkça mümkündür.

Web çalışanları ve standart çok iş parçacıklı ortam arasındaki temel fark, bellek kaynaklarının ana iş parçacığı ile paylaşılmamasıdır, bir nesneye yapılan başvuru bir iş parçacığından diğerine görünmez. İş parçacıkları mesaj alışverişi yoluyla iletişim kurarlar, bu nedenle olaya dayalı bir tasarım modelinin ardından bir senkronizasyon ve eşzamanlı yöntem çağrı algoritması uygulamak mümkündür.

İş parçacıkları arasında programlamanın yapılandırılmasına izin veren birçok çerçeve vardır, aralarında aynı anda programlamayı destekleyen bir OOP js çerçevesi olan OODK-JS, https://github.com/GOMServices/oodk-js-oop-for-js


5
Belleğin paylaşılması, ayrı bir işleme (örneğin fork () ve exec ()) karşılık gelen bir Evrenin kesin tanımıdır. İş parçacıkları nesneleri paylaşabilir, işlemler IPC kullanmalıdır. Web Çalışanları çok iş parçacıklı değildir.
felixfbecker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.