Linux'ta işlem başına maksimum iş parçacığı sayısı?


245

Linux altında bir işlem tarafından oluşturulabilecek maksimum iş parçacığı sayısı nedir?

Bu değer nasıl (mümkünse) değiştirilebilir?

Yanıtlar:


247

Linux'un işlem sınırı başına ayrı bir iş parçacığı yoktur, yalnızca sistemdeki toplam işlem sayısı sınırlaması vardır (iş parçacıkları aslında Linux'ta paylaşılan bir adres alanına sahip işlemlerdir):

cat /proc/sys/kernel/threads-max

Varsayılan, bellek sayfası sayısı / 4'tür. Bunu şu şekilde artırabilirsiniz:

echo 100000 > /proc/sys/kernel/threads-max

Ayrıca, tek bir kullanıcının oluşturabileceği işlemlerin (ve dolayısıyla iş parçacıklarının) sayısında bir sınır vardır, ulimit/getrlimitbu sınırlarla ilgili ayrıntılar için bakın.


3
/ Proc / sys / vm / max_map_count içindeki sınır, iş parçacığı sayısını da sınırlayabilir. Vurursanız, bu limiti çok artırmak güvenli olmalıdır.
Mikko Rantalainen

1
Robert: Linux dolaylı olarak işlem başına limit uygular. Ayrıntılar için cevabımı kontrol edin;)
codersofthedark

Benim ubuntu 12.04 bu değiştirmek için çalışıyorum ve komut ile değişmiyor. Ayrıca vi değiştirmek için çalıştı, ama E667: Fsync failedvi tasarruf etmeye çalışıyorum olsun .
Siddharth

4
@dragosrsupercool maksimum iş parçacığı toplam ram kullanılarak hesaplanır, sanal bellek yok
c4f4t0r

1
İş parçacığı başına yığın boyutu (sisteminizdeki varsayılan) miktarının, her şeyden daha fazla olması muhtemeldir. İş parçacığı yığın yığını boyutunu azaltmak toplam iş parçacığı sayısını artırmanın bir yoludur (bu nadiren iyi bir fikirdir).
Randy Howard

67

Bu, LINUX'un işlem sınırı başına ayrı bir iş parçacığı olmadığını söylemek YANLIŞ.

Linux dolaylı olarak işlem başına maksimum iş parçacığı sayısını uygular !!

number of threads = total virtual memory / (stack size*1024*1024)

Böylece, işlem başına iş parçacığı sayısı, toplam sanal bellek artırılarak veya yığın boyutu azaltılarak arttırılabilir. Ancak, yığın boyutunu çok fazla azaltmak, maksimum sanal bellek takas belleğine eşitken yığın taşması nedeniyle kod arızasına neden olabilir.

Makinenizi kontrol edin:

Toplam Sanal Bellek: ulimit -v(varsayılan sınırsızdır, bu nedenle bunu artırmak için takas belleğini artırmanız gerekir)

Toplam Yığın Boyutu: ulimit -s(varsayılan 8 Mb)

Bu değerleri artırma komutu:

ulimit -s newvalue

ulimit -v newvalue

* Yeni değeri, sınır olarak koymak istediğiniz değerle değiştirin.

Referanslar:

http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/


11
3 küçük detay dışında: 1. Linux bunu yapmaz, yığınların varlığı ve bellek ve adres alanının sonlu boyutta olması onunla hiçbir ilgisi yoktur. 2. Bir iş parçacığının yığınını oluştururken belirtmeniz gerekir, bu ne olursa olsun ulimit -s. Olası iş parçacığı kimlikleri olabildiğince çok iş parçacığı oluşturmak çok iyi (mantıklı değil, ancak mümkün). 64 bit Linux altında, iş parçacığı ID'lerinden daha fazla iş parçacığı oluşturmak bile kolayca "mümkündür" (elbette bu mümkün değildir, ancak yığın gittikçe). 3. Stack rezerv, taahhüt ve VM OC ile esp farklı şeyler vardır.
Damon

Evet, iş parçacığı sayısını artırmak için sanal belleği artırmanız veya yığın boyutunu azaltmanız gerekir. Raspberry Pi'de yığın belleğini varsayılan 8MB'dan 1MB'a düşürürseniz sanal belleği artırmanın bir yolunu bulamadım Her işlem için 1000'den fazla iş parçacığı elde edilebilir, ancak “ulimit -s” komutuyla yığın boyutunu küçültür bunu tüm iş parçacıkları için yapın. Bu nedenle, çözümüm “pthread_t” örneği “thread class” kullanmaktı, çünkü pthread_t her iş parçacığı için yığın boyutunu ayarlamama izin verdi. Son olarak, her biri 1MB yığın ile Raspberry
Pi'de

43

Pratik anlamda, sınır genellikle yığın alanı tarafından belirlenir. Her iş parçacığı 1MB yığın alırsa (Linux'ta varsayılan olup olmadığını hatırlayamıyorum), 32 bit sistem 3000 iş parçacığı (son gb çekirdeğe ayrılmış olduğunu varsayarak) sonra adres alanı bitecek .

Ancak, birkaç düzineden fazla iş parçacığı kullanırsanız büyük olasılıkla korkunç bir performans yaşarsınız. Er ya da geç, çok fazla bağlam anahtarlama yükü, zamanlayıcıda çok fazla yük vb. (Çok sayıda iş parçacığı oluşturmak, çok fazla bellek tüketmekten biraz daha fazlasını yapmaz. Ancak, gerçek yapacak birçok parçacığı , kullanılabilir CPU zamanı için savaşırken sizi yavaşlatacaktır.)

Bu sınırın daha alakalı olduğu durumlarda ne yapıyorsunuz?


3
Yığın için iş parçacığı başına 1 MB oldukça yüksektir, birçok programın bu kadar yığın alanının yakınında herhangi bir yere ihtiyacı yoktur. Performans, var olan iş parçacığı sayısına değil, çalıştırılabilir işlemlerin sayısına dayalı olacaktır . Şu anda 0.40 yük ile 1200+ iplik ile çalışan bir makinem var.
Robert Gamble

13
performans, ipliklerin ne yaptığına bağlıdır. fazla bir şey yapmazlarsa ve dolayısıyla daha az bağlam değiştirme yaparlarsa birkaç düzineden çok daha yükseğe gidebilirsiniz.
Corey Goldberg

yığını dinamik olarak büyüyor, sadece ilk sayfa yarasa dışı tahsis
Michael Pankov

28

linux uygun 100k konuları:

ulimit -s  256
ulimit -i  120000
echo 120000 > /proc/sys/kernel/threads-max
echo 600000 > /proc/sys/vm/max_map_count
echo 200000 > /proc/sys/kernel/pid_max 

 ./100k-pthread-create-app

Systemd sistemlerinde @Thomas'tan 2018 güncellemesi:

/etc/systemd/logind.conf: UserTasksMax=100000

4
Teşekkür ederim, nihayet 32k Java iş parçacığı sayısını kırmamı sağladı.
berezovskyi

1
Benim için çalışmıyor: $ ulimit -s 100000 $ ulimit -i 63645 $ cat / proc / sys / çekirdek / konuları-max 127626 $ cat / proc / sys / vm / max_map_count 600000 $ cat / proc / sys / kernel / pid_max 200000 $ java -Xmx4G -Xss256k -cp. ThreadCreation ... 11542 11543 java.lang.OutOfMemoryError: java.lang.Thread.start (Thread.java:717) öğesinde java.lang.Thread.start0 (Native Method) konumunda ThreadCreation.main ( ThreadCreation.java:15)
Martin Vysny

@MartinVysny ulimit -s = kb cinsinden iplik boyutu. 100MB iş parçacığı yığın boyutunda iş parçacıkları oluşturmaya çalışıyorsunuz.
Vladimir Kunschikov

Önerinizi kontrol etmeden eklediniz, @Thomas, yine de geri bildiriminiz için teşekkürler.
Vladimir Kunschikov

2
@VladimirKunschikov Teşekkürler dostum, çözümünüz gerçekten işe yaradı ve Thomas'a ek satır eklemesi için teşekkür ederim, bu satırda işe yaramayacağını onaylayabilirim.
BillHoo

14

@dragosrsupercool

Linux sanal iş parçacığını maksimum iş parçacığını hesaplamak için kullanmaz, ancak sistemde yüklü fiziksel ram

 max_threads = totalram_pages / (8 * 8192 / 4096);

http://kavassalis.com/2011/03/linux-and-the-maximum-number-of-processes-threads/

Çekirdek / fork.c

/* The default maximum number of threads is set to a safe
 * value: the thread structures can take up at most half
 * of memory.
 */
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);

Bu nedenle, iş parçacığı her sistem arasında farklıdır, çünkü kurulu ram farklı boyutlarda olabilir, Linux'un sanal belleği artırması gerekmediğini biliyorum, çünkü 32 bitte kullanıcı alanı için 3 GB ve çekirdek için 1 GB var, 64 bit'te Solaris'te gerçekleşen 128 TB sanal belleğimiz var, eğer sanal belleği artırmak istiyorsanız takas alanı eklemeniz gerekiyor.


11

Geri almak için:

cat /proc/sys/kernel/threads-max

Ayarlamak için:

echo 123456789 > /proc/sys/kernel/threads-max

123456789 = konu sayısı


Yazmaya çalışırken root ile bile izin almıyorum.
Kim

Bu yayınlandığından beri neredeyse on yıl geçti. Şu anki durum hakkında güncel değilim, ama çok şey değişmiş olabilir (ve muhtemelen değişmiş olabilir ...)
Vincent Van Den Berghe

perm-deny ile ilgili sorun eklenebilir ( >) bölüm kaybeder sudo: deneyinecho 12345678 | sudo tee -a /proc/sys/kernel/threads-max
dwanderson

10

Konu sayısı sınırı:

$ cat /proc/sys/kernel/threads-max 

Nasıl hesaplanır:

max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);

ve: x86_64 sayfa boyutu (PAGE_SIZE) 4K; Diğer tüm mimariler gibi, x86_64 her etkin iş parçacığı için bir çekirdek yığınına sahiptir. Bu iş parçacığı yığınları THREAD_SIZE (2 * PAGE_SIZE) büyük;

mempages için:

cat /proc/zoneinfo | grep spanned | awk '{totalpages=totalpages+$2} END {print totalpages}';

bu yüzden aslında sayı, iş parçacığı bellek yığını boyutunun ( ulimit -s) sınırlamasıyla ilgili değildir .

PS: iş parçacığı bellek yığını sınırlaması benim rhel VM 10M olduğunu ve 1.5G bellek için, bu VM sadece 150 iş parçacıkları verebilir?


5

Şimdi buna bakan herkes için, systemd sistemlerinde (benim durumumda, özellikle Ubuntu 16.04), cgroup pids.max parametresi tarafından uygulanan başka bir sınır var.

Bu, varsayılan olarak 12.288 olarak ayarlanmıştır ve /etc/systemd/logind.conf dosyasında geçersiz kılınabilir

Pids_max, thread-max, max_maps_count, ulimits, vb. Dahil olmak üzere başka tavsiyeler de geçerlidir.


5

benim durumumda Redhat Linux 2.6, ulimit ile iplik başına yığın boyutunu kontrol edin:

    ulimit -a
...
    stack size              (kbytes, -s) 10240

İş parçacıklarınızın her biri, yığını için bu miktarda bellek (10MB) atar. 32bit bir program ve maksimum 4GB adres alanı ile, bu maksimum 4096MB / 10MB = 409 iş parçacığıdır !!! Eksi program kodu, eksi yığın alanı muhtemelen gözlemlenen bir maks. 300 iş parçacığı.

64bit üzerinde derleyerek ve çalıştırarak veya ulimit -s 8192 hatta ulimit -s 4096 ayarlayarak bunu yükseltebilirsiniz. Ama bu tavsiye edilirse başka bir tartışmadır ...


4

Muhtemelen önemli değil. Sabit sayıda iş parçacığı (örneğin, 4 veya 8 işlemciniz varsa 4 veya 8) kullanmak için algoritmanızı tasarlayarak çok daha iyi bir performans elde edersiniz. Bunu iş kuyrukları, eşzamansız ES veya benzeri bir şeyle yapabilirsiniz.


3
Çok iş parçacığının amacı yalnızca performans değildir. Örneğin 4 çekirdekli işlemcide engelleme sistemine sahip 10 bağlantı noktasını dinliyorsunuz. Bu örnekte 4'ün anlamı yoktur.
obayhan

3

Kullanım nbio I / O çağrıları bu bloğu yapmak için daha fazla konuları gerekirse, kütüphane ya da her türlü o / i engellenmeyen


2

Sisteminize bağlı olarak, örnek bir program [bir döngüde işlemler oluşturarak] yazıp ps axo pid, ppid, rss, vsz, nlwp, cmd kullanarak kontrol edin. Artık iş parçacığı oluşturamadığında nlwp sayısını kontrol edin [nlwp sayı iş parçacığıdır] voila kitaplara gitmek yerine aptalca yanıtınızı aldınız


1

Kalıcı olarak ayarlamak için,

vim /etc/sysctl.conf

ve Ekle

kernel.threads-max = "value"

0

Linux'ta aşağıdaki dosyada tanımlanan maksimum iş parçacığı sayısını görebiliriz

cat / proc / sys / çekirdek / konuları-max

(VEYA)

sysctl -a | grep konuları-max


0

Mevcut değeri aşağıdaki komutla görebilirsiniz: cat / proc / sys / kernel / threads-max

Değeri aşağıdaki gibi de ayarlayabilirsiniz:

echo 100500> / proc / sys / çekirdek / iş parçacığı-max

Ayarladığınız değer kullanılabilir RAM sayfalarıyla karşılaştırılır. İş parçacığı yapıları kullanılabilir RAM sayfalarının 1 / 8'inden fazlasını kaplarsa, iş parçacığı-max buna göre azalır.


0

Evet, iş parçacığı sayısını artırmak için sanal belleği artırmanız veya yığın boyutunu azaltmanız gerekir. Raspberry Pi'de yığın belleğini varsayılan 8MB'dan 1MB'a düşürürseniz sanal belleği artırmanın bir yolunu bulamadım Her işlem için 1000'den fazla iş parçacığı elde edilebilir, ancak “ulimit -s” komutuyla yığın boyutunu küçültür bunu tüm iş parçacıkları için yapın. Bu nedenle, çözümüm “pthread_t” örneği “thread class” kullanmaktı, çünkü pthread_t her iş parçacığı için yığın boyutunu ayarlamama izin verdi. Son olarak, her biri 1MB yığın ile Raspberry Pi'de işlem başına 1000'den fazla iş parçacığını arşivlemek için hazırım.

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.