1

I'm making a version of the producer-consumer problem in C++20.

I need to work on a number of buffers, each having their own threads of producers and consumers, the number of threads being an argument. Seeing as the number of threads isn't a constant, I decided to store the threads in a vector, while the vectors of producers (consumers) for each buffer are stored in another vector.

I've created a minimal reproducible example of the code that's giving me an error:

#include <iostream>
#include <thread>
#include <semaphore>
#include <mutex>
#include <vector>

struct Buffer {
    std::counting_semaphore<1> full{0};
    std::counting_semaphore<1> empty{1};
};

void producer(Buffer buffer) {
    while(true)
    {
        buffer.empty.acquire();
        buffer.full.release();
    }
}
int main() {
    std::vector<std::vector<std::thread>> producers;
    for(int i = 0; i< 2; i++)
    {
        std::vector<std::thread> p;
        producers.push_back(p);
    }
    std::vector<Buffer> buffers;
    for(int i = 0; i<2; i++)
    {
        Buffer buffer;
        buffers.push_back(buffer);
    }
    int counter = 0;
    for(auto &vec: producers)
    {
        std::thread thread(producer, buffers[counter]); // error here
        vec.push_back(std::move(thread));
        counter++;
    }
}

The error on the indicated line is

error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues.

What could be causing this problem?

ubi
  • 61
  • 4
  • Please make a [mre] and indicate which line of code gives the error. – cigien Jan 28 '22 at 02:49
  • @cigien i've done the things u asked for. – ubi Jan 28 '22 at 03:03
  • `return producers, consumers;`?! – Davis Herring Jan 28 '22 at 03:11
  • @DavisHerring It's a remnant from the OP's original code. While it's a bug, it's not the bug OP is asking about, so I removed it. – cigien Jan 28 '22 at 03:18
  • Oh, I mainly code in Python for now so that's just something i assumed worked in c++ as well, unfortunately it's not that simple here, thanks for pointing that out. As @cigien pointed out, it doesn't have to do with the bug i asked about. – ubi Jan 28 '22 at 03:24
  • 1
    `std::counting_semaphore` is not copy or moveable. That means you cant pass a `Buffer` by value. – NathanOliver Jan 28 '22 at 03:35
  • @NathanOliver Thank you! That seems to have fixed the problem. – ubi Jan 28 '22 at 03:45
  • @NathanOliver If there isn't a reasonable duplicate for this question, could you flesh that out into an answer? – cigien Jan 28 '22 at 15:26
  • Does this answer your question? [Why the compiler complains that std::thread arguments must be invocable after conversion to rvalues?](https://stackoverflow.com/questions/61985888/why-the-compiler-complains-that-stdthread-arguments-must-be-invocable-after-co) – Paul Floyd Jul 16 '23 at 08:46

0 Answers0