I have to write a multi-thread application which counts how many times given numbers are divitable by 2. I can use only std::thread, std::future, std::promise for multi-threading - no mutex, condition variable etc. My idea is to give for each thread list of numbers. This is how i tried to do this:
unsigned int countTwo(int number) {
unsigned int count = 0;
while(number > 1 && number % 2 == 0) {
count++;
number /= 2;
}
return count;
}
unsigned int countTwoInList(const std::list<int> &numbers) {
unsigned int count = 0;
for(const auto &number : numbers) {
count += countTwo(number);
}
return count;
}
void f(const std::list<int> &numbers, std::promise<unsigned int>& countPromise) {
try {
countPromise.set_value(countTwoInList(numbers));
} catch (...) {
try {
countPromise.set_exception(std::current_exception());
}
catch (...) {}
}
}
const int THREADS_NUMBER = 2;
int main() {
int numbersCount;
std::cin >> numbersCount;
int total = 0;
std::thread myThreads[THREADS_NUMBER];
std::future<unsigned int> myFutures[THREADS_NUMBER];
int counter = 0;
unsigned int howManyPerThread = (unsigned int)ceil((double)numbersCount / THREADS_NUMBER);
std::list<int> nums;
try {
for (int i = 0; i < numbersCount; numbersCount++) {
int num;
std::cin >> num;
nums.push_back(num);
if (nums.size() == howManyPerThread || i == numbersCount - 1) {
std::promise<unsigned int> countPromise;
std::list<int> nums2(nums);
myFutures[counter] = countPromise.get_future();
myThreads[counter] = std::thread{[nums2, &countPromise] { f(nums2, countPromise); }};
counter++;
nums.clear();
}
}
for(int i = 0; i < counter; i++) {
myThreads[i].join();
}
for(int i = 0; i < counter; i++) {
total += myFutures[i].get();
}
} catch(const std::exception& e) {
std::cout << "exception from a thread: "<< e.what() << std::endl;
}
std::cout << total << std::endl;
}
And for data:
5
1
2
3
4
5
it stops with segmentation fault:
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff6f42700 (LWP 5780)]
[New Thread 0x7ffff6741700 (LWP 5781)]
[Thread 0x7ffff6f42700 (LWP 5780) exited]
Thread 3 "numbers" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff6741700 (LWP 5781)]
0x00000000004192ab in std::__future_base::_Result<unsigned int>::_M_set(unsigned int&&) (this=0x0,
__res=<unknown type in numbers, CU 0x0, DIE 0x17db0>) at /usr/include/c++/5/future:243
243 ::new (_M_storage._M_addr()) _Res(std::move(__res));
What am I doing wrong?
Aucun commentaire:
Enregistrer un commentaire