Jumlah maksimum utas per proses di Linux?

245

Berapa jumlah maksimum utas yang dapat dibuat oleh proses di Linux?

Bagaimana (jika mungkin) nilai ini dapat dimodifikasi?


sumber

Jawaban:

247

Linux tidak memiliki utas terpisah per batas proses, hanya batas jumlah total proses pada sistem (utas pada dasarnya hanya proses dengan ruang alamat bersama di Linux) yang dapat Anda lihat seperti ini:

cat /proc/sys/kernel/threads-max

Standarnya adalah jumlah halaman memori / 4. Anda dapat meningkatkan ini seperti:

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

Ada juga batasan jumlah proses (dan karenanya utas) yang dapat dibuat oleh satu pengguna, lihat ulimit/getrlimitdetail tentang batasan ini.

Robert Gamble
sumber
3
Batas dalam / proc / sys / vm / max_map_count juga dapat membatasi jumlah utas. Seharusnya aman untuk meningkatkan batas itu banyak jika Anda menekannya.
Mikko Rantalainen
1
Robert: Linux menerapkan per batas proses secara tidak langsung. Lihat jawaban saya untuk detail;)
codersofthedark
Saya mencoba untuk mengubah ini di Ubuntu 12,04 saya dan tidak berubah dengan perintah Anda. Saya juga mencoba vi untuk mengubahnya, tetapi saya dapatkan E667: Fsync failedketika saya mencoba menyimpan pada vi.
Siddharth
4
@dragosrsupercool utas maksimum dihitung menggunakan ram total, tidak ada memori virtual
c4f4t0r
1
Jumlah ukuran tumpukan per utas (default pada sistem Anda) lebih cenderung menjadi batas daripada yang lainnya. Mengurangi ukuran tumpukan per-utas adalah cara untuk meningkatkan jumlah total utas (walaupun itu jarang ide yang bagus).
Randy Howard
67

Ini SALAH untuk mengatakan bahwa LINUX tidak memiliki utas terpisah per batas proses.

Linux mengimplementasikan jumlah maksimum utas per proses secara tidak langsung !!

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

Dengan demikian, jumlah utas per proses dapat ditingkatkan dengan meningkatkan total memori virtual atau dengan mengurangi ukuran tumpukan. Tetapi, mengurangi ukuran stack terlalu banyak dapat menyebabkan kegagalan kode karena stack overflow sementara memori virtual maks sama dengan memori swap.

Periksa mesin Anda:

Total Virtual Memory: ulimit -v(standarnya tidak terbatas, jadi Anda perlu menambah memori swap untuk menambah ini)

Total Stack Size: ulimit -s(standarnya adalah 8Mb)

Perintah untuk meningkatkan nilai-nilai ini:

ulimit -s newvalue

ulimit -v newvalue

* Ganti nilai baru dengan nilai yang ingin Anda batasi.

Referensi:

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

codersofthedark
sumber
11
Kecuali 3 detail kecil: 1. Linux tidak melakukan ini, keberadaan tumpukan dan fakta bahwa memori dan ruang alamat berukuran terbatas tidak ada hubungannya dengan itu. 2. Anda harus menentukan tumpukan utas saat membuatnya, ini terlepas dari ulimit -s. Sangat mungkin (tidak masuk akal, tetapi mungkin) untuk membuat sebanyak mungkin utas karena ada ID utas yang mungkin. Di bawah 64 bit Linux, bahkan lebih mudah "mungkin" untuk membuat lebih banyak utas daripada yang ada ID utas (tentu saja itu tidak mungkin, tetapi sejauh tumpukan berjalan, itu adalah). 3. Stack reserve, commit dan VM adalah hal yang berbeda, terutama dengan OC.
Damon
Ya, untuk menambah nomor utas Anda perlu menambah memori virtual atau mengurangi ukuran tumpukan. Di Raspberry Pi saya tidak menemukan cara untuk meningkatkan memori virtual, jika penurunan ukuran stack dari default 8MB menjadi 1MB Mungkin mendapatkan lebih dari 1000 thread per proses tetapi kurangi ukuran stack dengan perintah "ulimit -s" buat ini untuk semua utas. Jadi, solusi saya adalah menggunakan "pthread_t" misalnya "kelas benang" karena pthread_t biarkan saya mengatur ukuran tumpukan per setiap utas. Akhirnya, saya dapat mengarsipkan lebih dari 1000 utas per proses di Raspberry Pi masing-masing dengan 1MB tumpukan
Deulis
43

Secara praktis, batas biasanya ditentukan oleh ruang tumpukan. Jika setiap utas mendapat tumpukan 1MB (saya tidak ingat apakah itu default di Linux), maka Anda sistem 32-bit akan kehabisan ruang alamat setelah 3000 utas (dengan asumsi bahwa gb terakhir dicadangkan untuk kernel) .

Namun, kemungkinan besar Anda akan mengalami kinerja yang buruk jika Anda menggunakan lebih dari beberapa lusin utas. Cepat atau lambat, Anda mendapatkan terlalu banyak konteks-switching overhead, terlalu banyak overhead dalam scheduler, dan sebagainya. (Membuat sejumlah besar utas tidak lebih dari memakan banyak memori. Tetapi banyak utas dengan pekerjaan aktual yang akan dilakukan akan memperlambat Anda saat mereka berjuang untuk waktu CPU yang tersedia)

Apa yang Anda lakukan di mana batas ini bahkan relevan?

jalf
sumber
3
1MB per utas untuk tumpukan cukup tinggi, banyak program tidak perlu mendekati ruang tumpukan sebanyak ini. Kinerja akan didasarkan pada jumlah proses yang bisa dijalankan , bukan jumlah utas yang ada. Saya memiliki mesin yang berjalan sekarang dengan 1200+ utas dengan beban 0,40.
Robert Gamble
13
kinerja tergantung pada apa yang dilakukan utas. Anda bisa menjadi jauh lebih tinggi dari beberapa lusin jika mereka tidak berbuat banyak dan karenanya kurang mengubah konteks.
Corey Goldberg
tumpukan tumbuh secara dinamis, hanya halaman awal yang dialokasikan
Michael Pankov
28

thread 100k yang tepat di linux:

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

Pembaruan 2018 dari @Thomas, pada sistem systemd:

/etc/systemd/logind.conf: UserTasksMax=100000
Vladimir Kunschikov
sumber
4
Terima kasih, akhirnya memungkinkan saya untuk menembus jumlah thread Java 32k.
berezovskyi
1
Tidak bekerja untuk saya: $ ulimit -s 100000 $ ulimit -i 63645 $ cat / proc / sys / kernel / threads-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: tidak dapat membuat utas asli baru di java.lang.Thread.start0 (Metode Asli) di java.lang.Thread.start (Thread.java:717) di ThreadCreation.main ( ThreadCreation.java:15)
Martin Vysny
@MartinVysny ulimit -s = ukuran utas dalam kb. jadi Anda mencoba membuat utas dengan ukuran tumpukan ulir 100MB.
Vladimir Kunschikov
menambahkan saran Anda tanpa memeriksa, @Thomas, terima kasih atas umpan baliknya.
Vladimir Kunschikov
2
@VladimirKunschikov Terima kasih sobat, solusi Anda benar-benar bekerja, dan terima kasih Thomas untuk menambahkan baris tambahan, saya dapat mengonfirmasi itu tidak akan berhasil tanpa garis itu.
BillHoo
14

@dragosrsupercool

Linux tidak menggunakan memori virtual untuk menghitung maksimum utas, tetapi ram fisik yang diinstal pada sistem

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

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

kernel / 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);

Jadi thread max berbeda antara setiap sistem, karena ram yang dipasang dapat dari ukuran yang berbeda, saya tahu Linux tidak perlu menambah memori virtual, karena pada 32 bit kami mendapat 3 GB untuk ruang pengguna dan 1 GB untuk kernel, pada 64 bit kami mendapat 128 TB memori virtual, yang terjadi pada Solaris, jika Anda ingin menambah memori virtual Anda perlu menambahkan ruang swap.

c4f4t0r
sumber
11

Untuk mengambilnya:

cat /proc/sys/kernel/threads-max

Untuk mengaturnya:

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

123456789 = # utas

Vincent Van Den Berghe
sumber
Saya mendapat izin ditolak ketika mencoba menulis, bahkan dengan root.
Kim
Yah, sudah hampir satu dekade sejak ini diposting. Saya tidak mengetahui keadaan terkini, tetapi banyak yang mungkin telah berubah (dan mungkin sudah) ...
Vincent Van Den Berghe
masalah dengan perm-deny mungkin append ( >) bagian kehilangan sudo: tryecho 12345678 | sudo tee -a /proc/sys/kernel/threads-max
dwanderson
10

Batas jumlah utas:

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

Bagaimana cara menghitungnya:

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

dan: x86_64 ukuran halaman (PAGE_SIZE) adalah 4K; Seperti semua arsitektur lainnya, x86_64 memiliki tumpukan kernel untuk setiap utas aktif. Tumpukan utas ini THREAD_SIZE (2 * PAGE_SIZE) besar;

untuk mempages:

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

jadi sebenarnya angkanya tidak terkait dengan batasan ukuran stack memory thread ( ulimit -s).

PS: batasan memory stack thread adalah 10M di rhel VM saya, dan untuk memori 1.5G, VM ini hanya mampu membeli 150 thread?

Albert Kong
sumber
5

Bagi siapa pun yang melihat ini sekarang, pada sistem systemd (dalam kasus saya, khususnya Ubuntu 16.04) ada batasan lain yang diberlakukan oleh parameter pg.max cgroup.

Ini diatur ke 12.288 secara default, dan dapat ditimpa di /etc/systemd/logind.conf

Saran lain masih berlaku termasuk pids_max, threads-max, max_maps_count, ulimits, dll.

Trent Lloyd
sumber
5

periksa ukuran tumpukan per utas dengan ulimit, dalam kasus saya Redhat Linux 2.6:

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

Setiap utas Anda akan mendapatkan jumlah memori (10MB) yang ditetapkan untuk tumpukan ini. Dengan program 32bit dan ruang alamat maksimum 4GB, maksimum hanya 4096MB / 10MB = 409 utas !!! Minus kode program, minus heap-space mungkin akan mengarah pada maks yang diamati. dari 300 utas.

Anda harus dapat meningkatkan ini dengan kompilasi dan berjalan pada 64bit atau pengaturan ulimit -s 8192 atau bahkan ulimit -s 4096. Tetapi jika ini disarankan adalah diskusi lain ...

Axel Podehl
sumber
4

Mungkin seharusnya tidak masalah. Anda akan mendapatkan kinerja yang jauh lebih baik merancang algoritme Anda untuk menggunakan jumlah utas yang tetap (mis., 4 atau 8 jika Anda memiliki 4 atau 8 prosesor). Anda dapat melakukan ini dengan antrian kerja, IO tidak sinkron, atau sesuatu seperti libevent.

twk
sumber
3
Tujuan dari multithreading bukan hanya kinerja. Misalnya Anda mendengarkan 10 port dengan sistem pemblokiran pada prosesor 4 inti. Dalam contoh ini tidak ada arti 4.
obayhan
3

Gunakan nbio pustaka i / o non-pemblokiran atau apa pun, jika Anda memerlukan lebih banyak utas untuk melakukan panggilan I / O yang memblokir

wefeqfw
sumber
2

Tergantung pada sistem Anda, cukup tulis program sampel [dengan membuat proses dalam satu lingkaran] dan periksa menggunakan ps axo pid, ppid, rss, vsz, nlwp, cmd. Ketika tidak dapat lagi membuat utas periksa nlwp hitung [nlwp adalah utas nomor] voila Anda mendapat jawaban bukti bodoh Anda alih-alih melalui buku

hasilnya
sumber
1

Untuk mengatur secara permanen,

vim /etc/sysctl.conf

dan tambahkan

kernel.threads-max = "value"
Matteo Zocca
sumber
0

Kita dapat melihat jumlah maksimum utas yang didefinisikan dalam file berikut di linux

cat / proc / sys / kernel / threads-max

(ATAU)

sysctl -a | grep threads-max

KrishnaKumar Madagani
sumber
0

Anda dapat melihat nilai saat ini dengan perintah-cat / proc / sys / kernel / threads-max berikut

Anda juga dapat mengatur nilai seperti

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

Nilai yang Anda tetapkan akan diperiksa terhadap halaman RAM yang tersedia. Jika struktur utas menempati lebih dari 1/8) dari halaman RAM yang tersedia, utas-maks akan dikurangi.

Arif
sumber
0

Ya, untuk menambah nomor utas Anda perlu menambah memori virtual atau mengurangi ukuran tumpukan. Di Raspberry Pi saya tidak menemukan cara untuk meningkatkan memori virtual, jika penurunan ukuran stack dari default 8MB menjadi 1MB Mungkin mendapatkan lebih dari 1000 thread per proses tetapi kurangi ukuran stack dengan perintah "ulimit -s" buat ini untuk semua utas. Jadi, solusi saya adalah menggunakan "pthread_t" misalnya "kelas benang" karena pthread_t biarkan saya mengatur ukuran tumpukan per setiap utas. Akhirnya, saya tersedia untuk mengarsipkan lebih dari 1000 utas per proses di Raspberry Pi masing-masing dengan tumpukan 1MB.

Deulis
sumber