چرا thread ها درست اجرا نمیشن؟ - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

وبـــلاگ هــفت خــط کــد


آموزش های برنامه نویسی
۳۹۵ نفر آنلاین
۱۷۱ عضو و ۲۲۴ مهمان در سایت حاضرند

چرا thread ها درست اجرا نمیشن؟

+1 امتیاز

سلام.

کد زیر اببینید:

#include <iostream>
#include <thread>
#include <vector>

using namespace std;
void func(int& counter)
{
	for (int i = 0; i < 100; ++i) {
		++counter;
		std::this_thread::sleep_for(std::chrono::milliseconds(1));
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	int counter = 0;
	std::vector<std::thread> threads;
	for (int i = 0; i < 10; ++i) {
		threads.push_back(std::thread{ func, std::ref(counter) });
	}
	for (auto& t : threads) {
		t.join();
	}
	std::cout << "Result = " << counter << std::endl;

	return 0;
}

قاعدتاً 10 تا thread داریم که هر کدام 100 بار counter را افزایش می دن خروجی باید 1000 باشه در صورتیکه به صورت تصادفی عددی حول حوش 1000 چاپ میشه به نظرتون اشکال کار کجاست؟

 

ممنون

سوال شده دی 21, 1393  بوسیله ی shab (امتیاز 194)   8 22 30

2 پاسخ

+2 امتیاز

مشکل این هست که باید قبل از تغییر متغیر به اشتراک گذاشته شده در n تا thread  از std::mutex استفاده کنید .

یا بجای int از  std::atomic<int استفاده کنید .

به این شکل :

#include <iostream>
#include <thread>
#include <vector>
#include <atomic>

void func(std::atomic_int_least32_t& counter)
{
    for (int i = 0; i < 100; ++i) {
        ++counter;
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }
}
int main()
{
    std::atomic_int_least32_t counter(0);
    std::vector<std::thread> threads;
    for (int i = 0; i < 10; ++i) {
        threads.push_back(std::thread{ func, std::ref(counter) });
    }
    for (auto& t : threads) {
        t.join();
    }
    std::cout << "Result = " << counter << std::endl;
 
    return 0;
}

 

پاسخ داده شده دی 21, 1393 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
+2 امتیاز

علاوه بر توضیحاتی که داده شد نکته در کد وجود داره اگر متغیر counter به صورت atomic استفاده شه آن زمان شما در تابع func با هر بار افزایش counter افت پرفرمنس خواهید داشت .بهتره اینکار را یکبار در انتهای تابع انجام بدید  کد خود را به صورت زیر تغییر بدید.

void func(std::atomic<int> counter){
int temp_counter = 0;
for (int i = 0; i < 100; ++i) {
++temp_counter;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
counter += temp_counter;
}

 

پاسخ داده شده دی 22, 1393 بوسیله ی مصطفی ساتکی (امتیاز 21,998)   24 34 75
...