mardi 20 novembre 2018

Multi-thread work with fixed number of threads

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