I am new to threads, I am trying to simulate the critical section race condition problem in this code.
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
using namespace std::chrono;
int x = 20;
void increment()
{
++x;
}
void decrement()
{
--x;
}
int main()
{
thread t1(increment);
thread t2(decrement);
cout << x;
return 0;
}
But, this code terminates with SIGABRT.
terminate called without an active exception
21
Why I am getting SIGABRT in this code?
You must call join for the threads so that they are properly terminated
t1.join();
t2.join();
Related
This program will crash cause the threads are tangled... One could be pushing while the other is trying to erase.
How can I make this work?
#include <thread>
#include <vector>
using namespace std;
vector<int> v_test;
void push()
{
v_test.push_back(0);
}
void erase()
{
if (v_test.size() > 0)
{
v_test.erase(v_test.begin());
}
}
int main()
{
thread w0(push);
thread w1(erase);
while (true) { Sleep(1000); }
return 0;
}
You need to synchronize the threads so they coordinate their access to the vector. For example, by using a std::mutex, eg:
#include <thread>
#include <mutex>
#include <vector>
using namespace std;
vector<int> v_test;
mutex m_sync;
void push()
{
lock_guard<mutex> lock(m_sync);
v_test.push_back(0);
}
void erase()
{
lock_guard<mutex> lock(m_sync);
if (v_test.size() > 0)
{
v_test.erase(v_test.begin());
}
}
int main()
{
thread w0(push);
thread w1(erase);
while(true) {Sleep(1000);}
return 0;
}
I'm trying to do this simple program, where I want to use the take and append functions, which access a buffer implemented with a list, in a producer-consumer problem:
#ifndef buf_h
#define buf_h
#include <list>
using std::list;
#include <mutex>
using std::mutex;
#include <condition_variable>
using std::condition_variable;
class Buffer
{
public:
Buffer(int cap);
void append(int shift);
int take();
private:
list<double> Buffer_;
int capacity_;
int count_;
mutex mutex_;
condition_variable not_full_;
condition_variable not_empty_;
};
#endif
This is buffer:
#include "buf.h"
#include <list>
using std::list;
#include <mutex>
using std::mutex;
using std::unique_lock;
#include <condition_variable>
using std::condition_variable;
Buffer::Buffer(int capacity)
: Buffer_(capacity,0), capacity_{capacity}, count_{0}
{
}
void Buffer::append(int shift)
{
unique_lock<mutex> mlock(mutex_);
while(count_== capacity_)
not_full_.wait(mlock);
Buffer_.push_back(shift);
++count_;
not_empty_.notify_one();
}
int Buffer::take()
{
unique_lock<mutex> mlock(mutex_);
while(count_ == 0)
not_empty_.wait(mlock);
int w = Buffer_.front();
Buffer_.pop_front();
--count_;
not_full_.notify_one();
return w;
}
This is main:
#include <iostream>
using std::cout;
using std::endl;
#include <fstream>
using std::ifstream;
#include <thread>
using std::thread;
#include "buf.h"
Buffer B1{20};
void producer(int id){
B1.append(id);
}
void consumer(){
int w = B1.take();
cout<< w <<endl;
}
int main()
{
for(int i=0; i<5; ++i){
thread prod(producer, i);
thread cons(consumer);
prod.join();
cons.join();
}
return 0;
}
I don't understand why if I use push_back() in append, I get all 0 as output, when instead I should get this:
0
1
2
3
4
If I use push_front() the output is correct. Can anyone help me?
In your constructor:
Buffer_(capacity,0)
This does not do what you think it does. If you inspect what's in the Buffer_ immediately after construction you will discover that it's not empty, and the resulting program's behavior becomes easy to explain.
TLDR: the initializes the buffer with a whole bunch of values, which are all 0, which completely messes up the logic in the rest of the code which assumes that the buffer is initially empty.
I am currently trying to create a sort of "factory" pattern in a class, whose instances should be Threads that have their own certain operation procedure. I have currently declared a global variable isFinished in order to end the operation of the worker thread, however, somehow the operation does not stop after the variable state is changed, and the worker thread does not do the std::thread::join() operation in order to finish working. I am new to threads, and in C++ in general and I don't really know what is wrong so any help would be greatly appreciated.
Here is the code:
\\main.cpp
#include <iostream>
#include <thread>
#include <atomic>
#include "Sender.h"
int main()
{
isFinished = false; //set false for worker thread
Sender mSender; //Create thread object for worker
std::cin.get(); //Trigger by pressing enter
isFinished = true; //exit worker while loop
mSender.join(); //wait for the worker thread to finish execution
}
\\sender.cpp
#include <iostream>
#include <thread>
#include <atomic>
#include "Sender.h"
void Sender::SenderWorkflow()
{
while (!isFinished)
{
std::cout << "Working... \n";
}
}
\\sender.h
#include <iostream>
#include <thread>
#include <atomic>
static std::atomic<bool> isFinished;
class Sender {
public:
std::thread worker;
Sender()
: worker(&Sender::SenderWorkflow, this)
{
}
void SenderWorkflow();
void join() {
worker.join(); \\std::thread::join()
}
};
The problem is that you are using a static variable in the global scope. static in a namespace scope is used to hide the variable or function in the object file so that the linker can't see it while linking another object file for another cpp file. In practice static is used only inside the cpp file itself. Since you declared it inside the header each translation unit that includes it will get a different instance of the variable because the linker can't see the same variable across objects file. To solve this :
1- move the declaration of the static variable to the cpp file and make an accessor function in the header file:
\\sender.h
#include <atomic>
const std::atomic<bool>& checkIsFinished();
void setFinished();
\\sender.cpp
static std::atomic<bool> isFinished;
const std::atomic<bool>& checkIsFinished() { return isFinished; }
void setFinished() { isFinished = true; }
2- or use inline variable (since c++17) in the header file:
\\sender.h
#include <atomic>
inline std::atomic<bool> isFinished;
3 - or better and the correct design : make the variable local as member of the class, the less global variables the better !
\\sender.h
#include <atomic>
class Sender {
public:
std::thread worker;
Sender()
: worker(&Sender::SenderWorkflow, this)
{
}
void SenderWorkflow();
void join() {
isFinished = true;
worker.join(); \\std::thread::join()
}
private:
std::atomic<bool> isFinished = false;
};
I'm trying to make threads using C++'s standard library via functions.
#include <iostream>
#include <thread>
using namespace std;
void print()
{
printf("PRINT\n");
printf("PRINT2\n");
}
void createThread()
{
thread newThread(print);
}
int main()
{
createThread();
cin.get();
}
the program compiles and runs but once the thread is finished it creates a "debug error". Any thoughts?
The problem is that your thread object goes out of scope before you call its detach() or join() member.
Try this:
int main()
{
thread newThread(print);
...
newThread.join();
return 0;
}
If your "debug error" means the compiler error message, you should check if -pthread flag is set. That is compile the code with
$ g++ -std=c++11 main.cpp -pthread -o main
If your "debug error" means the runtime error, you should remember to join() after you create a thread.
source code:
#include <iostream>
#include <thread>
void print()
{
std::cout << "PRINT" << std::endl;;
std::cout << "PRINT 2" << std::endl;;
}
void create_thread()
{
std::thread print_thread(print);
print_thread.join(); // remember to join()
}
int main()
{
create_thread();
return 0;
}
In addition, you may pay attention to 4 additional points:
using namespace std is not recommended.
remember to join() after you create a thread
return 0 for main()
printf() is in stdio.h. use std::cout for iostream
#include <iostream>
#include <string>
#include <thread>
#include <future>
int main()
{
auto pms = std::promise<std::string>();
auto ftr = pms.get_future();
std::thread([&](){pms.set_value("hello world");});
ftr.wait();
std::cout << ftr.get() << std::endl;
return 0;
}
According to this link, std::future::wait blocks until the result becomes avaiable.
However, the code above can't print anything. Obviously the main thread has finished before the thread of pms.set_value finished.
Why doesn't ftr.wait() block?
The problem is not that std::future::wait doesn't block. The real problem is that you have a race condition between the thread that you spawned, doing it's work, and the destruction of std::thread (temporary) object in the main thread.
Because of that, abort is called in the destructor of std::thread if the thread is still joinable.
Working code:
#include <iostream>
#include <string>
#include <thread>
#include <future>
#include <chrono>
int main()
{
auto pms = std::promise<std::string>();
auto ftr = pms.get_future();
std::thread thread ([&](){pms.set_value("hello world");});
ftr.wait();
std::cout << ftr.get() << std::endl;
thread.join ();
return 0;
}
Note, if you don't join the thread explicitly, you would still have the same race condition (since it's possible that main can do its work faster, than the thread can clean itself up.
Demo of working example: here.
Alternatively you can detach the thread and use promise::set_value_at_thread_exit rather than set_value
#include <iostream>
#include <string>
#include <thread>
#include <future>
#include <chrono>
int main()
{
auto pms = std::promise<std::string>();
auto ftr = pms.get_future();
std::thread([&](){pms.set_value_at_thread_exit("hello world");}).detach();
ftr.wait();
std::cout << ftr.get() << std::endl;
return 0;
}