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);
Related
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <thread>
std::mutex mtx;
void func2() {
mtx.lock();
std::cout << "here is 2" << std::endl;
mtx.unlock();
}
void func1() {
mtx.lock();
std::cout << "here is 1" << std::endl;
func2();
mtx.unlock();
}
int main() {
func1();
}
but if I modify the main func as follows, it cause dead lock
int main() {
std::thread t1(func1);
t1.join();
}
I complied both two by "g++ test.cpp -std=c++11 -lpthread"
Calling lock in the same thread twice (without unlocking the mutex) is undefined. From cppreference:
If lock is called by a thread that already owns the mutex, the behavior is undefined: for example, the program may deadlock.
It may deadlock. Or it may not. The behavior is undefined.
Note that std::recursive_mutex can be locked multiple times (though only up to some unspecified limit). However, code that needs a recursive mutex is more complicated. In your example it would be easier to remove the locking from func1, because it is only called when the mutex is already locked. In general it isn't that simple.
I've been having an error declaring a thread class object. I tried this code and it gave me the error "'thread' was not declared in this scope". If it helps, I'm compiling to Windows using MinGW GCC.
#include <iostream>
#include <thread>
using namespace std;
void func(){
cout << "Hello from thread 2\n";
}
int main(){
cout << "Hello from thread 1\n";
thread t2(func);
t2.join();
return 0;
}
Compiling gives me "error: 'thread' was not declared in this scope"
Threads are missing in mingw, but you can use some library like this one mingw-std-threads.
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
I am getting a C++ error with threading:
terminate called without an active exception
Aborted
Here is the code:
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
template<typename TYPE>
class blocking_stream
{
public:
blocking_stream(size_t max_buffer_size_)
: max_buffer_size(max_buffer_size_)
{
}
//PUSH data into the buffer
blocking_stream &operator<<(TYPE &other)
{
std::unique_lock<std::mutex> mtx_lock(mtx);
while(buffer.size()>=max_buffer_size)
stop_if_full.wait(mtx_lock);
buffer.push(std::move(other));
mtx_lock.unlock();
stop_if_empty.notify_one();
return *this;
}
//POP data out of the buffer
blocking_stream &operator>>(TYPE &other)
{
std::unique_lock<std::mutex> mtx_lock(mtx);
while(buffer.empty())
stop_if_empty.wait(mtx_lock);
other.swap(buffer.front());
buffer.pop();
mtx_lock.unlock();
stop_if_full.notify_one();
return *this;
}
private:
size_t max_buffer_size;
std::queue<TYPE> buffer;
std::mutex mtx;
std::condition_variable stop_if_empty,
stop_if_full;
bool eof;
};
I modeled my code around this example:
http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
What am I doing wrong and how do I fix the error?
When a thread object goes out of scope and it is in joinable state, the program is terminated. The Standard Committee had two other options for the destructor of a joinable thread. It could quietly join -- but join might never return if the thread is stuck. Or it could detach the thread (a detached thread is not joinable). However, detached threads are very tricky, since they might survive till the end of the program and mess up the release of resources. So if you don't want to terminate your program, make sure you join (or detach) every thread.
How to reproduce that error:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <thread>
using namespace std;
void task1(std::string msg){
cout << "task1 says: " << msg;
}
int main() {
std::thread t1(task1, "hello");
return 0;
}
Compile and run:
el#defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el#defiant ~/foo4/39_threading $ ./s
terminate called without an active exception
Aborted (core dumped)
You get that error because you didn't join or detach your thread.
One way to fix it, join the thread like this:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <thread>
using namespace std;
void task1(std::string msg){
cout << "task1 says: " << msg;
}
int main() {
std::thread t1(task1, "hello");
t1.join();
return 0;
}
Then compile and run:
el#defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el#defiant ~/foo4/39_threading $ ./s
task1 says: hello
The other way to fix it, detach it like this:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <thread>
using namespace std;
void task1(std::string msg){
cout << "task1 says: " << msg;
}
int main()
{
{
std::thread t1(task1, "hello");
t1.detach();
} //thread handle is destroyed here, as goes out of scope!
usleep(1000000); //wait so that hello can be printed.
}
Compile and run:
el#defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el#defiant ~/foo4/39_threading $ ./s
task1 says: hello
Read up on detaching C++ threads and joining C++ threads.
Eric Leschinski and Bartosz Milewski have given the answer already. Here, I will try to present it in a more beginner friendly manner.
Once a thread has been started within a scope (which itself is running on a thread), one must explicitly ensure one of the following happens before the thread goes out of scope:
The runtime exits the scope, only after that thread finishes executing. This is achieved by joining with that thread. Note the language, it is the outer scope that joins with that thread.
The runtime leaves the thread to run on its own. So, the program will exit the scope, whether this thread finished executing or not. This thread executes and exits by itself. This is achieved by detaching the thread. This could lead to issues, for example, if the thread refers to variables in that outer scope.
Note, by the time the thread is joined with or detached, it may have well finished executing. Still either of the two operations must be performed explicitly.
First you define a thread. And if you never call join() or detach() before calling the thread destructor, the program will abort.
As follows, calling a thread destructor without first calling join (to wait for it to finish) or detach is guarenteed to immediately call std::terminate and end the program.
Either implicitly detaching or joining a joinable() thread in its
destructor could result in difficult to debug correctness (for detach)
or performance (for join) bugs encountered only when an exception is
raised. Thus the programmer must ensure that the destructor is never
executed while the thread is still joinable.
As long as your program die, then without detach or join of the thread, this error will occur. Without detaching and joining the thread, you should give endless loop after creating thread.
int main(){
std::thread t(thread,1);
while(1){}
//t.detach();
return 0;}
It is also interesting that, after sleeping or looping, thread can be detach or join. Also with this way you do not get this error.
Below example also shows that, third thread can not done his job before main die. But this error can not happen also, as long as you detach somewhere in the code.
Third thread sleep for 8 seconds but main will die in 5 seconds.
void thread(int n) {std::this_thread::sleep_for (std::chrono::seconds(n));}
int main() {
std::cout << "Start main\n";
std::thread t(thread,1);
std::thread t2(thread,3);
std::thread t3(thread,8);
sleep(5);
t.detach();
t2.detach();
t3.detach();
return 0;}
yes, the thread must be join(). when the main exit
This code freezes VS2010 sp1:
// STC_14_1.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include <exception>
#include <iostream>
#include <cstdlib>
using std::cerr;
using std::cout;
using std::cin;
void my_new_handler()
{
cerr << "Mem. alloc failed.";
std::exit(-1);
}
//std::unexpected_handler std::set_unexpected(std::unexpected_handler);
class STC
{
std::new_handler old;
public:
STC(std::new_handler n_h):old(std::set_new_handler(n_h))
{ }
~STC()
{
std::set_unexpected(old);
}
};
int main(int argc, char* argv[])
{
STC stc(&my_new_handler);
while (true)
{
auto tmp = new int[50000];
}
return 0;
}
Is it that I'm doing something wrong or it's VS's problem?
Your loop is endless:
while (true)
{
auto tmp = new int[50000];
}
You have to define a condition to exit outside of the loop. In counterpart, VS will be frozen iterating through the loop and draining memory from the heap (since you allocate a new block of memory in every iteration).
EDIT: Your handler is not called because it has to be defined as void __cdecl:
void __cdecl no_memory () {
cout << "Failed to allocate memory!\n";
exit (1);
}
Since handler is not called, the problem is in endless loop.
It works on my VS 2010.
When you say 'freezes', are you sure that it's not just that the code is still actually running and has not hit the new handler code yet. I tried running the example set_new_handler code from the MSDN here, and it still took a minute or so and the example is allocating 5000000 at a time rather than 50000.