Error compiling with <list> C++ - c++

I don't know why it doesn't compile of I erase the comment in line
/*******************************/
waitThread.push_front(workerID);
/******************************/
Only if I leave the comment, it compiles...otherwise, I get a long exception ending with "declared here"...
/usr/include/c++/4.6/thread:126:5: error: declared here
maybe there is some problem with the definition of ...
Can you explain me?
/* g++ -std=c++0x -o manyThreads manyThreads.cpp -pthread */
#include <thread>
#include <iostream>
#include <mutex>
#include <time.h>
#include <list>
std::list<std::thread::id> myList;
std::mutex mutex;
std::list<std::thread> waitThread;
void insertList(std::thread::id identifier) {
mutex.lock();
myList.push_front(identifier);
mutex.unlock();
}
int main() {
std::list<std::thread::id>::iterator id;
std::list<std::thread>::iterator threadsIter;
int counter;
for(counter=0; counter<6; counter++) {
std::thread workerID(insertList, workerID.get_id());
/*******************************/
waitThread.push_front(workerID);
/******************************/
}
for(threadsIter=waitThread.begin(); threadsIter !=waitThread.end();threadsIter++) {
threadsIter->join();
}
for(id=myList.begin(); id != myList.end(); id++) {
std::cout << *id << "\n";
}
return 0;
}

std::thread is not copyable so you can't call push_front with it. It makes no sense to copy a thread, what would it do?
You can perhaps move the thread onto the list using
waitThread.push_front(std::move(workerID));
which will of course invalidate the thread object after that line.
However this line looks strange too :-
std::thread workerID(insertList, workerID.get_id());
I doubt it's valid to call get_id on an object that isn't constructed at that point.

std::thread is not copyable so you would have to move it in:
waitThread.push_front(std::move(workerID));
alternatively, you can move it by passing a temporary:
waitThread.push_front(std::thread(insertList, workerID.get_id());

It's not a comment, but a valid and (probably) essential statement in your program:
/*******************************/ -- comment
waitThread.push_front(workerID); -- statement
/******************************/ --comment

Related

Take multiple arguments to the thread function c++11

I have an array of threads and in for loop I should create a thread to all of them.
The problem is that one of the parameters is std::move(promise_var) and another one is structure. When I try to compile it compile gives me an error:
error: no matching function for call to ‘std::thread::thread(void (&)(Function), Structure [nNumThreads], std::remove_reference<std::promise<const char*>&>::type)’
So, here is the simplified version of code...
func(struct Structure, std::promise<const char *> && v_Promise){
//doing work
}
main(){
std::thread a_Threads[5];
for(int8_t i = 0; i < 5; i++){
a_Threads[i] = std::threads(func, Structure, std::move(v_promise[i]));
}
}
(Not putting in a comment so that I can append the code properly) I completed the code you submitted so that it compiles and I can confirm that the code below compiles and runs fine with the command g++ test.cpp -std=c++11 -pthread:
#include <iostream>
#include <thread>
#include <future>
using namespace std;
struct Structure{
int el1;
int el2;
};
void func(struct Structure, std::promise<const char *> && v_Promise){
cout<<"Hello"<<endl;
//doing work
}
int main(){
std::thread a_Threads[5];
Structure my_struct;
std::promise<const char*> v_promise;
for(int8_t i = 0; i < 5; i++){
a_Threads[i] = std::thread(func, my_struct, std::move(v_promise));
}
}
Please cross-reference this against any typos or information that you might have omitted.

Initializing C++11 threads from within an if statement

I am implimenting threads in C++11 and experienceing a compilation issue whenever I initiate a thread from within an if statement.
The error I am receiving is:
file.cpp: In function ‘int main(int, char**)’:
file.cpp:16:2: error: ‘thread1’ was not declared in this scope
thread1.join();
When I move the thread outside of an if statement everything compiles and runs fine.
I am using g++ version 4.8.2 and using the -std=c++11 compiler option.
This code will not compile
#include <unistd.h>
#include <thread>
#include <iostream>
void testthread() {
std::cout << "Thread was run" << std::endl;
}
int main(int argc, char**argv) {
if (true) {
std::thread thread1(testthread);
}
sleep(1);
thread1.join();
return 0;
}
This code compiles and runs as expected
#include <unistd.h>
#include <thread>
#include <iostream>
void testthread() {
std::cout << "Thread was run" << std::endl;
}
int main(int argc, char**argv) {
std::thread thread1(testthread);
sleep(1);
thread1.join();
return 0;
}
The body of an if() statement is a block scope so the lives any variables created within it are bound to its scope. This means that thread1 isn't accessible outside of the if() statement.
Instead you can default construct the thread and then assign it to a new one:
std::thread thread1;
if (true) {
thread1 = std::thread(testthread)
}
You are declaring the thread variable inside the if block. It is only visible there.
If you really need to initialize it inside the if block and use it outside, you can use a pointer and allocate it inside the if block.
std::thread* pThread1 = nullptr;
if (true) {
pThread1 = new std::thread(testthread);
}
sleep(1);
pThread1->join();
delete(pThread1);

Why is this cppreference demo program causing a segmentation fault?

I'm reviewing a variant of the std::move function by testing it on my compiler. For some reason this program fails in both latest clang++ and g++4.8. In my opinion this looks like a correct program that should work.
g++-4.8 -std=c++1y -O3 -Wall -pthread main.cpp && ./a.out
terminate called without an active exception
/tmp/1370796977-600590525/cmd.sh: line 7: 22819 Aborted (core dumped) ./a.out
#include <iostream>
#include <vector>
#include <list>
#include <iterator>
#include <thread>
#include <chrono>
void f(int n)
{
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "thread " << n << " ended" << '\n';
}
int main()
{
std::vector<std::thread> v;
v.emplace_back(f, 1);
v.emplace_back(f, 2);
v.emplace_back(f, 3);
std::list<std::thread> l;
for(auto& t : l) t.join();
}
I notice that the part that causes the error is the emplace_back lines. When I remove them the program compiles normally. Why is this happening and why is it failing on all compilers I've tried thus far?
You are not joining the threads in main(). You need
for(auto& t : v) t.join();
// ^ Look, v not l
Alternatively, place this line before your original loop to move the threads from the v into l:
std::move(v.begin(), v.end(), std::back_inserter(l));
for(auto& t : l) t.join();
you try iterate over empty l, but 'join is not accomplished for real threads
You seem to leave the list empty, and exit main with unjoined threads in v.
IIRC destructor of std::thread calls terminate if not joined.

ThreadPool with boost::asio does not quit?

I have the following minmal example of a thread pool made with boost::asio.
#include <queue>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> // remove me (only for io)
class ThreadPool
{
public:
void work_as_mainthread(void) { m_io_service.run(); }
ThreadPool(int poolSize = 4) : timer(m_io_service)
{
timer.expires_from_now(boost::posix_time::seconds(1)); // this line does not affect the problem
m_pWork.reset( new boost::asio::io_service::work(m_io_service) );
for ( int i = 0; i < poolSize; ++i)
m_threadGroup.create_thread( boost::bind(&boost::asio::io_service::run, &m_io_service) );
}
~ThreadPool()
{
m_pWork.reset();
m_threadGroup.join_all();
}
private:
boost::asio::io_service m_io_service;
boost::asio::deadline_timer timer;
boost::shared_ptr<boost::asio::io_service::work> m_pWork;
boost::thread_group m_threadGroup;
};
int main()
{
int n_threads = 2;
ThreadPool pool(n_threads);
pool.work_as_mainthread();
// this line is never reached...
return 0;
}
If you like, you can compile it like this:
g++ -Wall -g -lboost_thread -lboost_date_time -lboost_system main.cpp -o main
What makes me wonder is that the program does not stop. What I do is calling io_service::run, but without any "work" for it. io_services without work quit themselves, as said in the boost::asio docs. Now, why does my program never quit?
When you create a boost::asio::io_service::work object, that keeps the io_service from completing.
// This line keeps the io_service running
m_pWork.reset( new boost::asio::io_service::work(m_io_service) );
If you want it to stop, you would need to destroy that work object, like this:
// stop the worker(s)
m_pWork.reset();
It's up to you to find an appropriate time/place to do this. I would suggest calling timer.async_wait(), then in the handler you can reset your work object to see how this all should be working together.
See this portion of the documentation.

boost::thread and std::unique_ptr

Is it somehow possible to pass an std::unique_ptr as a parameter to a boost::thread constructor? If not, what is the best workaround?
A small example:
// errors: g++ uniqueptr_thread.cpp -std=c++0x
#include <iostream>
#include <memory>
#include <boost/thread.hpp>
class TestThread{
public:
void operator()(std::unique_ptr<int> val){
std::cout << "parameter: " << val << std::endl;
}
};
int main(int argc, char* argv[]){
std::unique_ptr<int> ptr(new int(5));
boost::thread th( new TestThread(), std::move(ptr));
}
This compiles and runs for me:
#include <iostream>
#include <memory>
#include <thread>
class TestThread{
public:
void operator()(std::unique_ptr<int> val){
std::cout << "parameter: " << *val << std::endl;
}
};
int main()
{
std::unique_ptr<int> ptr(new int(5));
std::thread th( TestThread(), std::move(ptr));
th.join();
}
But it has to be in C++0x mode. I don't know if the boost move emulation is good enough to do this or not.
A std::unique_ptr is, as the name suggests, unique. There can be only one!
Now, if your thread function takes a std::unique_ptr&&, and you use std::move to move the parameter in the thread function, then you can pass the std::unique_ptr. But then your copy will be empty, since you moved it to the other thread.
If std::move does not work, then your compiler or standard library may have bugs in it. I imagine that transferring ownership across threads like this isn't a common occurrence. And C++11 is still fairly new.
Are you sure your problem is with the unique_ptr? Why does your example use new to create your functor? That line should just read:
boost::thread th(TestThread(), std::move(ptr));