Pertanyaan yang relevan :
Tentang C ++ 11:
- C ++ 11: std :: thread pooled?
- Apakah async (launch :: async) di C ++ 11 membuat kumpulan thread menjadi usang karena menghindari pembuatan thread yang mahal?
Tentang Peningkatan:
Bagaimana cara mendapatkan kumpulan utas untuk mengirim tugas , tanpa membuat dan menghapusnya berulang-ulang? Ini berarti utas persisten untuk melakukan sinkronisasi ulang tanpa bergabung.
Saya memiliki kode yang terlihat seperti ini:
namespace {
std::vector<std::thread> workers;
int total = 4;
int arr[4] = {0};
void each_thread_does(int i) {
arr[i] += 2;
}
}
int main(int argc, char *argv[]) {
for (int i = 0; i < 8; ++i) { // for 8 iterations,
for (int j = 0; j < 4; ++j) {
workers.push_back(std::thread(each_thread_does, j));
}
for (std::thread &t: workers) {
if (t.joinable()) {
t.join();
}
}
arr[4] = std::min_element(arr, arr+4);
}
return 0;
}
Alih-alih membuat dan menggabungkan utas setiap iterasi, saya lebih suka mengirim tugas ke pekerja saya utas setiap iterasi dan hanya membuatnya sekali.
c++
multithreading
c++11
threadpool
stdthread
Yktula
sumber
sumber
Jawaban:
Anda dapat menggunakan Perpustakaan C ++ Thread Pool, https://github.com/vit-vit/ctpl .
Maka kode yang Anda tulis dapat diganti dengan yang berikut
Anda akan mendapatkan jumlah utas yang diinginkan dan tidak akan membuat dan menghapusnya berulang-ulang di iterasi.
sumber
results[j] = p.push([&arr, j](int){ arr[j] +=2; });
Ini disalin dari jawaban saya ke posting lain yang sangat mirip, semoga bisa membantu:
1) Mulai dengan jumlah utas maksimum yang dapat didukung sistem:
2) Untuk implementasi threadpool yang efisien, setelah utas dibuat sesuai dengan Num_Threads, lebih baik tidak membuat yang baru, atau menghancurkan yang lama (dengan bergabung). Akan ada penalti kinerja, bahkan mungkin membuat aplikasi Anda berjalan lebih lambat daripada versi serial.
Setiap utas C ++ 11 harus menjalankan fungsinya dengan loop tak terbatas, terus-menerus menunggu tugas baru untuk diraih dan dijalankan.
Berikut ini cara melampirkan fungsi tersebut ke kumpulan utas:
3) Fungsi Infinite_loop_
Ini adalah loop "while (true)" menunggu antrian tugas
4) Buat fungsi untuk menambahkan pekerjaan ke Antrian Anda
5) Bind fungsi sewenang-wenang ke Antrian Anda
Setelah Anda mengintegrasikan bahan-bahan ini, Anda memiliki kolam threading dinamis Anda sendiri. Utas ini selalu berjalan, menunggu pekerjaan selesai.
Saya minta maaf jika ada beberapa kesalahan sintaksis, saya mengetik kode ini dan dan saya memiliki memori yang buruk. Maaf bahwa saya tidak dapat memberikan Anda kode kumpulan utas lengkap, yang akan melanggar integritas pekerjaan saya.
Edit: untuk menghentikan pool, panggil metode shutdown ():
sumber
std::vector
tidak memerlukan elemennya untuk dapat disalin. Anda dapat menggunakan vektor dengan jenis bergerak-satunya (unique_ptr
,thread
,future
, dll).condition.wait
juga mencari variabelstop_
dan periksaif (stop_ == true) { break;}
?Kumpulan utas berarti bahwa semua utas Anda berjalan, sepanjang waktu - dengan kata lain, fungsi utas tidak pernah kembali. Untuk memberi thread sesuatu yang bermakna untuk dilakukan, Anda harus merancang sistem komunikasi antar-thread, baik untuk tujuan memberi tahu thread bahwa ada sesuatu yang harus dilakukan, maupun untuk mengkomunikasikan data pekerjaan yang sebenarnya.
Biasanya ini akan melibatkan semacam struktur data bersamaan, dan setiap utas mungkin akan tidur pada beberapa jenis variabel kondisi, yang akan diberitahukan ketika ada pekerjaan yang harus dilakukan. Setelah menerima pemberitahuan, satu atau beberapa utas bangun, memulihkan tugas dari struktur data bersamaan, memprosesnya, dan menyimpan hasilnya dengan cara yang analog.
Utas kemudian akan melanjutkan untuk memeriksa apakah ada lebih banyak pekerjaan yang harus dilakukan, dan jika tidak kembali tidur.
Hasilnya adalah bahwa Anda harus merancang semua ini sendiri, karena tidak ada gagasan alami tentang "pekerjaan" yang berlaku secara universal. Ini sedikit kerja, dan ada beberapa masalah halus yang harus Anda selesaikan. (Anda dapat memprogram di Go jika Anda menyukai sistem yang menangani pengelolaan utas untuk Anda di belakang layar.)
sumber
Threadpool pada intinya adalah seperangkat utas yang semuanya terikat pada fungsi yang bekerja sebagai perulangan kejadian. Utas ini tanpa henti akan menunggu tugas untuk dieksekusi, atau penghentian mereka sendiri.
Pekerjaan threadpool adalah untuk menyediakan antarmuka untuk mengirimkan pekerjaan, menentukan (dan mungkin memodifikasi) kebijakan menjalankan pekerjaan ini (aturan penjadwalan, instantiasi utas, ukuran kumpulan), dan memantau status utas dan sumber daya terkait.
Jadi untuk kumpulan serbaguna, seseorang harus mulai dengan mendefinisikan apa tugas itu, bagaimana itu diluncurkan, disela, apa hasilnya (lihat gagasan tentang janji dan masa depan untuk pertanyaan itu), peristiwa seperti apa yang harus ditanggapi oleh utas-utas tersebut untuk, bagaimana mereka akan menanganinya, bagaimana peristiwa-peristiwa ini akan dibedakan dari yang ditangani oleh tugas-tugas. Ini bisa menjadi sangat rumit seperti yang Anda lihat, dan memaksakan pembatasan tentang cara kerja utas, karena solusinya menjadi semakin terlibat.
Perkakas saat ini untuk menangani peristiwa cukup barebone (*): primitif seperti mutex, variabel kondisi, dan beberapa abstraksi di atas itu (kunci, hambatan). Tetapi dalam beberapa kasus, abstrasi ini mungkin tidak layak (lihat pertanyaan terkait ini ), dan seseorang harus kembali menggunakan primitif.
Masalah lain harus dikelola juga:
Bagaimana ini akan bermain di pengaturan Anda?
Jawaban untuk pertanyaan serupa ini menunjuk pada implementasi yang ada yang dimaksudkan untuk meningkatkan dan stl.
Saya menawarkan implementasi threadpool yang sangat kasar untuk pertanyaan lain, yang tidak membahas banyak masalah yang diuraikan di atas. Anda mungkin ingin membangunnya. Anda mungkin juga ingin melihat kerangka kerja yang ada dalam bahasa lain, untuk mencari inspirasi.
(*) Saya tidak melihat itu sebagai masalah, justru sebaliknya. Saya pikir itu adalah semangat C ++ yang diwarisi dari C.
sumber
sumber
Sesuatu seperti ini mungkin membantu (diambil dari aplikasi yang berfungsi).
Anda bisa menggunakannya seperti ini:
Perlu diingat bahwa menciptakan kembali mekanisme antrian asinkron yang efisien bukanlah hal sepele.
Boost :: asio :: io_service adalah implementasi yang sangat efisien, atau sebenarnya adalah kumpulan pembungkus khusus platform (misalnya membungkus port penyelesaian I / O pada Windows).
sumber
std::thread
sudah cukup?std
untukboost::thread_group
.boost::thread_group
adalah kumpulanboost::thread
instance. Tapi tentu saja, itu sangat mudah untuk menggantiboost::thread_group
denganvector
daristd::thread
s.Sunting: Ini sekarang membutuhkan C ++ 17 dan konsep. (Pada 9/12/16, hanya g ++ 6.0+ yang cukup.)
Pengurangan template jauh lebih akurat karena itu, jadi itu sepadan dengan upaya mendapatkan kompiler yang lebih baru. Saya belum menemukan fungsi yang membutuhkan argumen templat eksplisit.
Itu juga sekarang mengambil objek callable yang sesuai ( dan masih statis typesafe !!! ).
Ini juga sekarang termasuk kolam utas prioritas threading hijau opsional menggunakan API yang sama. Kelas ini hanya POSIX. Ini menggunakan
ucontext_t
API untuk beralih tugas userspace.Saya membuat perpustakaan sederhana untuk ini. Contoh penggunaan diberikan di bawah ini. (Saya menjawab ini karena itu adalah salah satu hal yang saya temukan sebelum saya memutuskan untuk menulisnya sendiri.)
Anda dapat melewati
async
fungsi apa pun dengan nilai pengembalian (atau batal) apa pun dan (atau tidak ada) argumen apa pun dan itu akan mengembalikan yang sesuaistd::future
. Untuk mendapatkan hasilnya (atau hanya menunggu sampai tugas selesai) Anda memanggilget()
masa depan.Inilah github: https://github.com/Tyler-Hardin/thread_pool .
sumber
Ini adalah implementasi thread pool lain yang sangat sederhana, mudah dimengerti dan digunakan, hanya menggunakan pustaka standar C ++ 11, dan dapat dilihat atau dimodifikasi untuk penggunaan Anda, harus menjadi starter yang bagus jika Anda ingin menggunakan thread kolam:
https://github.com/progschj/ThreadPool
sumber
Anda dapat menggunakan thread_pool dari boost library:
Anda juga dapat menggunakan threadpool dari komunitas open source:
sumber
Threadpool tanpa ketergantungan di luar STL sepenuhnya memungkinkan. Baru-baru ini saya menulis pustaka threadpool hanya header kecil untuk mengatasi masalah yang sama persis. Ini mendukung pengubahan ukuran pool dinamis (mengubah jumlah pekerja saat runtime), menunggu, berhenti, berhenti, melanjutkan dan seterusnya. Semoga bermanfaat.
sumber