Thread vs ThreadPool


137

Apa perbedaan antara menggunakan utas baru dan utas dari kumpulan utas? Manfaat kinerja apa yang ada dan mengapa saya harus mempertimbangkan untuk menggunakan utas dari kumpulan daripada yang saya buat secara eksplisit? Saya memikirkan secara khusus. NET di sini, tetapi contoh umum baik-baik saja.

Jawaban:


111

Kolam benang akan memberikan manfaat untuk operasi yang sering dan relatif singkat

  • Menggunakan kembali utas yang telah dibuat daripada membuat yang baru (proses yang mahal)
  • Menghambat laju pembuatan utas saat ada lonjakan permintaan untuk item pekerjaan baru (saya yakin ini hanya di .NET 3.5)

    • Jika Anda mengantrekan 100 tugas kumpulan utas, ini hanya akan menggunakan utas sebanyak yang telah dibuat untuk melayani permintaan ini (katakan 10 misalnya). Kumpulan utas akan sering melakukan pemeriksaan (saya percaya setiap 500ms dalam 3,5 SP1) dan jika ada tugas yang antri, itu akan membuat satu utas baru. Jika tugas Anda cepat, jumlah utas baru akan sedikit dan menggunakan kembali 10 utas atau lebih untuk tugas pendek akan lebih cepat daripada membuat 100 utas di depan.

    • Jika beban kerja Anda secara konsisten memiliki sejumlah besar permintaan kumpulan utas yang masuk, kumpulan utas akan menyesuaikan dirinya dengan beban kerja Anda dengan membuat lebih banyak utas di kumpulan dengan proses di atas sehingga ada lebih banyak utas yang tersedia untuk memproses permintaan

    • periksa Di sini untuk info lebih mendalam tentang bagaimana kumpulan benang berfungsi di bawah kap

Membuat utas baru sendiri akan lebih sesuai jika pekerjaan akan berjalan relatif lama (mungkin sekitar satu atau dua detik, tetapi itu tergantung pada situasi spesifik)

@Krzysztof - Thread Pool thread adalah thread latar belakang yang akan berhenti saat thread utama berakhir. Utas yang dibuat secara manual berada di latar depan secara default (akan tetap berjalan setelah utas utama berakhir), tetapi dapat disetel ke latar belakang sebelum memanggil Mulai.


5
Satu-satunya hal yang saya ingin tahu adalah pernyataan berikut dari MSDN ( msdn.microsoft.com/en-us/library/1c9txz50.aspx ) "Utas latar belakang hanya dijalankan ketika jumlah utas latar depan yang dieksekusi lebih kecil daripada jumlah prosesor . ". Jadi apakah itu berarti bahwa ketika membagi pekerjaan di antara inti, utas latar depan mendapat prioritas?
cdiggins

1
➤ Anda tidak dapat membatalkan atau memutus thread dari kumpulan thread. ➤ Anda tidak dapat bergabung dengan utas dari kumpulan utas. Untuk mencapai itu, Anda harus menggunakan beberapa mekanisme lain
Zinov

15

Threadpool yang dikelola .NET: -

  • Ukurannya sendiri berdasarkan beban kerja saat ini dan perangkat keras yang tersedia
  • Berisi utas pekerja dan utas port penyelesaian (yang secara khusus digunakan untuk melayani IO)
  • Dioptimalkan untuk sejumlah besar operasi yang berumur pendek

Ada implementasi kumpulan thread lain yang mungkin lebih sesuai untuk operasi yang berjalan lama.

Secara khusus, gunakan kumpulan thread untuk mencegah aplikasi Anda membuat terlalu banyak thread. Fitur terpenting dari threadpool adalah antrean pekerjaan. Artinya, setelah mesin Anda cukup sibuk, threadpool akan mengantrekan permintaan daripada segera menelurkan lebih banyak utas.

Jadi, jika Anda akan membuat sejumlah kecil utas yang dibatasi, buatlah sendiri. Jika Anda tidak dapat menentukan di muka berapa banyak utas yang dapat dibuat (misalnya, dibuat sebagai respons terhadap IO yang masuk), dan pekerjaan mereka akan berumur pendek, gunakan threadpool. Jika Anda tidak tahu berapa banyak, tetapi pekerjaan mereka akan berjalan lama, tidak ada apa pun di platform yang dapat membantu Anda - tetapi Anda mungkin dapat menemukan implementasi threadpool alternatif yang sesuai.


Di .NET, dapatkah Anda menggunakan port penyelesaian tanpa kumpulan utas? Saya berasumsi bahwa metode I / O asinkron adalah satu-satunya cara (di .NET) dan bahwa mereka menggunakan kumpulan utas
Karg

11

juga

new Thread().Start()

memunculkan thread Foreground yang tidak akan mati jika Anda menutup program Anda. Utas ThreadPool adalah utas latar belakang yang mati saat Anda menutup aplikasi.


11
Anda selalu dapat menyetel utas ke latar belakang. Mereka hanya di latar depan secara default.
Kris Erickson

3
nemo: var t = Thread baru (...); t.BackgroundThread = true; t. Mulai ();
Ricardo Amores

18
Klarifikasi tentang istilah "program". Aplikasi desktop berjalan dalam suatu proses, dan memiliki setidaknya satu utas latar depan yang mengelola UI. Proses itu akan terus berjalan selama memiliki utas latar depan. Saat Anda menutup aplikasi desktop, thread UI latar depan berhenti, tetapi Anda belum tentu menghentikan prosesnya jika aplikasi memiliki thread latar depan lain.
G-Wiz

8

Saya penasaran tentang penggunaan sumber daya relatif untuk ini dan dan menjalankan benchmark pada laptop Intel i5 dual-core 2012 saya menggunakan rilis .net 4.0 yang dibangun di windows 8. Thread Pools mengambil rata-rata 0,035ms untuk memulai di mana Threads mengambil rata-rata 5,06 MS. Dengan kata lain Utas di kumpulan dimulai sekitar 300x lebih cepat untuk sejumlah besar utas berumur pendek. Setidaknya dalam rentang yang diuji (100-2000) utas, total waktu per utas tampak cukup konstan.

Ini adalah kode yang dijadikan tolok ukur:

    for (int i = 0; i < ThreadCount; i++) {
        Task.Run(() => { });
    }

    for (int i = 0; i < ThreadCount; i++) {
        var t = new Thread(() => { });
        t.Start();
    }

masukkan deskripsi gambar di sini


5
Saya pikir itu karena ThreadPool menggunakan kembali utas yang dibuat alih-alih membuat yang baru (yang sangat mahal)
fabriciorissetto


1

Penyimpanan lokal benang bukanlah ide yang baik dengan kumpulan benang. Ini memberi benang sebuah "identitas"; tidak semua utas sama lagi. Sekarang kumpulan utas sangat berguna jika Anda hanya membutuhkan sekumpulan utas yang identik, siap untuk melakukan pekerjaan Anda tanpa overhead pembuatan.


1

Jika Anda membutuhkan banyak utas, Anda mungkin ingin menggunakan ThreadPool. Mereka menggunakan kembali utas sehingga menghemat biaya pembuatan utas.

Jika Anda hanya membutuhkan satu utas untuk menyelesaikan sesuatu, Utas mungkin paling mudah.


1

Kebutuhan utama utas theadpool adalah untuk menangani tugas-tugas kecil pendek yang diharapkan selesai hampir seketika. Penangan interupsi perangkat keras sering kali berjalan dalam konteks penumpukan yang tidak sesuai untuk kode non-kernel, tetapi penangan interupsi perangkat keras mungkin menemukan bahwa callback penyelesaian I / O mode pengguna harus dijalankan sesegera mungkin. Membuat utas baru untuk tujuan menjalankan hal seperti itu akan sangat berlebihan. Memiliki beberapa utas yang dibuat sebelumnya yang dapat dikirim untuk menjalankan callback penyelesaian I / O atau hal serupa lainnya jauh lebih efisien.

Aspek kunci dari utas tersebut adalah bahwa jika metode penyelesaian I / O selalu selesai pada dasarnya secara instan dan tidak pernah memblokir, dan jumlah utas yang saat ini menjalankan metode tersebut setidaknya sama dengan jumlah prosesor, satu-satunya cara utas lainnya dapat berjalan sebelum salah satu metode yang disebutkan di atas selesai jika salah satu blok metode lain atau waktu eksekusinya melebihi potongan waktu threading normal; tidak satu pun dari hal tersebut yang akan sering terjadi jika kumpulan utas digunakan sebagaimana mestinya.

Jika suatu metode tidak dapat diharapkan untuk keluar dalam 100 md atau lebih dari saat mulai dieksekusi, metode tersebut harus dijalankan melalui beberapa cara selain kumpulan utas utama. Jika seseorang memiliki banyak tugas untuk dilakukan yang memerlukan banyak CPU tetapi tidak akan diblokir, mungkin berguna untuk mengirimkannya menggunakan kumpulan utas aplikasi (satu per inti CPU) yang terpisah dari threadpool "utama", karena menggunakan lebih banyak utas daripada inti akan menjadi kontraproduktif saat menjalankan tugas-tugas intensif CPU yang tidak memblokir. Namun, jika sebuah metode membutuhkan waktu satu detik atau lebih untuk dieksekusi, dan akan menghabiskan sebagian besar waktunya diblokir, metode tersebut kemungkinan besar harus dijalankan di thread khusus, dan hampir pasti tidak dijalankan di thread main-threadpool. Jika operasi yang berjalan lama perlu dipicu oleh sesuatu seperti callback I / O,


0

Secara umum (saya belum pernah menggunakan .NET), kumpulan utas akan digunakan untuk tujuan manajemen sumber daya. Ini memungkinkan batasan untuk dikonfigurasi ke dalam perangkat lunak Anda. Ini juga dapat dilakukan untuk alasan kinerja, karena pembuatan utas baru mungkin mahal.

Mungkin juga ada alasan spesifik sistem. Di Java (sekali lagi saya tidak tahu apakah ini berlaku untuk .NET), pengelola utas dapat menerapkan variabel khusus utas karena setiap utas ditarik dari kumpulan, dan membatalkannya ketika dikembalikan (cara umum untuk meneruskan sesuatu seperti sebuah identitas).

Contoh kendala: Saya hanya memiliki 10 koneksi db, jadi saya hanya mengizinkan 10 utas pekerja untuk mengakses database.

Ini tidak berarti bahwa Anda tidak boleh membuat utas Anda sendiri, tetapi ada beberapa kondisi yang membuat Anda dapat menggunakan kumpulan.


0

Menggunakan pool adalah ide yang bagus, jika Anda tidak tahu atau tidak bisa mengontrol berapa banyak thread yang akan dibuat.

Hanya memiliki masalah dengan formulir yang menggunakan utas untuk memperbarui beberapa bidang dari database pada peristiwa posisi berubah dari kontrol daftar (hindari freez). Butuh waktu 5 menit bagi pengguna saya untuk mengalami kesalahan dari database (terlalu banyak koneksi dengan Access) karena dia mengubah posisi daftar terlalu cepat ...

Saya tahu ada cara lain untuk menyelesaikan masalah dasar (termasuk tidak menggunakan akses) tetapi penggabungan adalah awal yang baik.


0

Benang :

  1. Membuat Thread jauh lebih lambat daripada menggunakan Thread-pool.
  2. Anda dapat mengubah prioritas utas.
  3. Jumlah maksimal utas dalam proses yang terkait dengan sumber daya.
  4. Thread ada di level OS dan dikontrol oleh OS.
  5. Menggunakan Thread adalah opsi yang lebih baik saat tugas berjalan relatif lama

Thread-Pool :

  1. Menjalankan Thread di kumpulan thread jauh lebih cepat daripada membuat Thread secara langsung.
  2. Anda tidak dapat mengubah prioritas thread yang dijalankan berdasarkan Thread-pool.
  3. Hanya ada satu kumpulan Thread per proses.
  4. Thread-pool dikelola oleh CLR.
  5. Thread-pool berguna untuk operasi jangka pendek.
  6. Jumlah Thread di Thread-pool terkait dengan beban aplikasi.
  7. Tugas TPL dijalankan berdasarkan Thread-pool
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.