C++ Threads Deadlock Mutex Lock Aborted - c++

I am trying to remove a deadlock from a program. The problem is that the program keeps giving me aborted. The point is to write data to a file. But when a deadlock occurs the thread should wait and continue later on rather than aborting.
#include <iostream>
#include <unistd.h>
#include <fstream>
#include <vector>
#include <thread>
#include <mutex>
#include <exception>
#include <condition_variable>
using namespace std;
std::mutex mtx;
ofstream myfile;
condition_variable cv;
void lock()
{
mtx.lock();
}
void unlock()
{
mtx.unlock();
}
void writeToFile(int threadNumber){
myfile << "[";
for(int j =1; j <= 10; j++){
int num = j * threadNumber;
string line = std::to_string(num) + " ";
myfile << line;
}
myfile << "]";
//mtx.unlock();
}
void threadFunction(int threadNumber)
{
// int x = 0;
// int y = 0;
try{
lock();
if (threadNumber % 2 == 0)
sleep(rand() % 4 + 1);
writeToFile(threadNumber);
throw exception();
unlock();
}
catch(...){
cout << "Something went wrong!" << endl;
throw exception();
}
}
int main (int argc, char const *argv[]) {
myfile.open ("mutex.txt");
std::set_terminate([](){
std::cout << "Unhandled exception\n";
// Here I want to fix the deadlock if something goes wrong. But I keep getting Abroted
});
int len;
cout << "Enter Number of threads : ";
cin >> len;
std::thread t[len + 1];
for(int i =1; i <= len;i++){
t[i] = std::thread(threadFunction, i);
cout << "Created Thread : " <<t[i].get_id()<<endl;
}
for(int i =1; i <= len;i++){
t[i].join();
}
myfile.close();
return 0;
}
Output
Enter Number of threads : 5
Created Thread : 1992414288
Created Thread : 1982854224
Created Thread : 1974465616
Created Thread : 1966077008
Created Thread : 1957688400
Something went wrong!
Unhandled exception
Aborted
How can I avoid the aborted and let the thread wait.
Update: Included all the relevant code...

Do not lock() / unlock() mutexes manually. That's error prone. Use guards instead. mtx.unlock(); after throwing the exception won't be called.
Here's how your code should look:
try{
std::lock_guard<std::mutex> lock(mtx);
if (threadNumber % 2 == 0)
sleep(rand() % 4 + 1);
writeToFile(threadNumber);
throw exception();
}
catch(...){
cout << "Something went wrong!" << endl;
throw exception();
}
To avoid deadlocks in general that locking and unlocking of multiple mutexes needs to be done in reverse order. So if one thread uses something like
{
std::lock_guard<std::mutex> lock1(mtx1);
std::lock_guard<std::mutex> lock2(mtx2);
// ... exception thrown somewhere
}
this is guaranteed since the destructors of std::lock_guard are guaranteed to be called in the reverse order these were constructed.

Related

Why my thread is not running at all? (Cpp multithreading)

I am new to threading, and i am trying to write a function that keep outputing an variable while i should be able to change that variable at runtime, and the output should change to my input once I input a new value in. By the following program is not running as i expected, whats wrong here? is there anything i can reference to so i can build this funciton out?
int a;
void* ptr;
void* Input(void* arg){
while(true){
std::cin >> a;
std::cout << std::endl;
}
return ptr;
}
void* Output(void *arg){
while(true){
std::cout << a << std::endl;
}
return ptr;
}
int main(){
pthread_t GetInput;
pthread_create(&GetInput,NULL,Input,NULL);
pthread_t GetOutput;
pthread_create(&GetOutput,NULL,Output,NULL);
}
Your main thread is not waiting for your child thread and exited when main() returned. To make your main thread to wait for children finish their jobs, you should call pthread_join() for them.
int main(){
pthread_t GetInput;
pthread_create(&GetInput,NULL,Input,NULL);
pthread_t GetOutput;
pthread_create(&GetOutput,NULL,Output,NULL);
pthread_join(GetInput, NULL);
pthread_join(GetOutput, NULL);
return 0;
}
Here's another alternative using std::async() for your code.
#include <chrono>
#include <future>
#include <iostream>
#include <mutex>
int a;
std::mutex mtx_;
void Input(void* arg) {
while (true) {
int tmp_a;
std::cin >> tmp_a;
{
std::lock_guard<std::mutex> lock(mtx_);
a = tmp_a;
}
std::cout << std::endl;
}
}
void Output(void* arg) {
while (true) {
{
std::lock_guard<std::mutex> lock(mtx_);
std::cout << a << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main() {
auto ft_in = std::async(std::launch::async, Input, &a);
auto ft_out = std::async(std::launch::async, Output, &a);
ft_in.wait();
ft_out.wait();
return 0;
}
Well,I don't know how to use pthread.
And it seems Mr.john-park or Ms.john-park already gave a answer.
But I think use thread is a better choice.
To use it,we should:
#include<thread>
After that,if u want to start a new thread,and "connect" it with a function(In fact,we usually do)
There is a class named thread.
First,we should
thread *thread name*(*function name*);
WARNING:function nameshould be without "(" and ")"
May because here should be a pointer.
Then,to the question.
Suppose we wrote:
thread GetInput(Input);
thread GetOutput(Output);
When u want to stop GetOutput some time and run GetInput,
just
GetInput.join()
Here's a not so good example:
#include <iostream>
#include <thread>
using namespace std;
void f1()
{
while (true)
{
cout << "THREAD 1!" << endl;
}
}
void f2()
{
for (int i = 0; i < 10; i++)
cout << "THREAD 2!" << endl;
thread t1(f1);
t1.join();
for (int i = 0; i < 10; i++)
cout << "THREAD 2!" << endl;
}
int main()
{
thread t2(f2);
return 0;
}
First,we started t2.
Then t2 started t1.
Now we can know why we use join().
If we don't join(),
It'll be hard for us to read the output because it'll close the cmd window quickly.
But we can know,
after t2 end,
return 0;
ran.
But if we used join()
Here's the output:
THREAD 2!
THREAD 2!
THREAD 2!
...(THREAD 2!*10)
THREAD 1!
THREAD 1!
...(Always THREAD 1!)

How to change this notify_one so that it chooses a random thread?

Thanks in advance for any help.
Trying to make a program that would create 6 threads, then each 2 seconds randomly choose one and make it print its number. I am obviously doing something wrong, because it just keeps printing 0-1-2-3-4-5 endlessly. The code is below.
Main question is, what should i do to make random threads unlock?
#include <thread>
#include <memory>
#include <chrono>
#include <condition_variable>
std::condition_variable* cv = new std::condition_variable();
std::mutex cv_m;
void threadFunc(std::shared_ptr<bool> flag2, int id)
{
while (true)
{
std::unique_lock<std::mutex> lock(cv_m);
cv->wait(lock);
if (true)
if (*flag2) std::cout << "Thread" << " " << id << std::endl;
}
}
int main() {
std::shared_ptr<bool> f2 = std::make_shared<bool>(false);
std::thread threads[6];
for (int i = 0; i < 6; i++)
threads[i] = std::thread(threadFunc, f2, i);
*f2 = true;
while (true)
{
cv->notify_one();
std::this_thread::sleep_for(std::chrono::seconds(2));
}
return 0;
}
You can use a condition variable for each thread, it should be false for each thread at the beginning, then change a random condition variable to true and notify all, this will make a random thread to wake up (the thread that owns that condition variable)
here is the full solution
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <unistd.h>
#include "UserInterruptHandler.h"
using namespace std;
UserInterruptHandler h;
condition_variable conditionalVariable;
mutex mtx;
bool flag = true;
void myMethod(int id, bool *canWork) {
unique_lock<mutex> ul(mtx);
while (flag) {
conditionalVariable.wait(ul,[=]{return *canWork;});
if(!flag)
break;
cout << "thread " << id << endl;
}
cout << "thread " << id << " exits.." << endl;
}
int main() {
cout << "input thread count" << endl;
int n;
cin >> n;
thread myThreads[n];
bool *canWork = new bool[n];
for (int i = 0; i < n; i++) {
canWork[i] = false;
myThreads[i] = thread(myMethod, i + 1, &canWork[i]);
}
while (!h.checkInterruption()) {
int i = rand() % n;
canWork[i] = true;
conditionalVariable.notify_all();
canWork[i] = false;
usleep(1000);
}
flag = false;
int i = 0;
for (thread &th:myThreads) {
canWork[i++] = true;
conditionalVariable.notify_all();
if (th.joinable())
th.join();
}
}
notice that here I am using header UserInterruptHandler.h to handle CTR+C event to end all threads gracefully

Why this conditon variable is not working?

I was trying to understand the condition_variable available in C++ standard. So in the below test code I have written, I expect the func1 to be woken up after printing 50 numbers in main thread but here it prints all numbers only from main thread?
Could you please help me here to understand condition_variable better to indicate a certain thread to wake up
I have tried to understand condition variable using below code:
#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
std::mutex mu;
std::condition_variable multiple;
bool isLoaded = false;
void func1()
{
std::unique_lock<std::mutex> unLock(mu);
multiple.wait(unLock, []() {return isLoaded; });
for (int i = 0; i < 100; i++)
{
cout << "This is from thread; " << i << endl;
}
}
int main()
{
std::thread t1(func1);
std::lock_guard<std::mutex> gaurd(mu);
cout << std::thread::hardware_concurrency()<< endl;
for (int i = 0; i < 100; i++)
{
if (i == 50)
{
isLoaded = true;
multiple.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(4));
}
cout << "This is from main; " << i << endl;
}
t1.join();
getchar();
return 0;
}
You never release mu in main thread. Try something like this:
int main()
{
std::thread t1(func1);
cout << std::thread::hardware_concurrency()<< endl;
for (int i = 0; i < 100; i++)
{
if (i == 50)
{
{
std::lock_guard<std::mutex> gaurd(mu);
isLoaded = true;
}
multiple.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(4));
}
cout << "This is from main; " << i << endl;
}
t1.join();
getchar();
return 0;
}
In general you need to keep your locks for absolute minimum of time you can.
You are taking mutex mu at start of your program and never let it go, so any other code under this mutex will never be executed.
Instead you should only hold it when you changing shared variables, something like:
{
std::lock_guard<std::mutex> gaurd(mu);
isLoaded = true;
multiple.notify_one();
}

Synchronisation before pthread_cond_broadcast

I want to send a broadcast signal from the main thread to all the other threads waiting for a condition. It seems to me that the broadcast signal comes to early to the threads.
#include <iostream>
#include <pthread.h>
#define NUM 4
#define SIZE 256
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_barrier_t barrier;
class cache{
int lv1;
public:
int write(int i){
lv1=i;
pthread_cond_broadcast(&cond);
}
};
cache c[NUM];
void *thread(void *arg){
int i = (int)arg;
for(;;){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
cout << "Thread: "<< i << endl;
//do some work
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t tid[NUM];
pthread_barrier_init(&barrier,NULL,NUM+1);
for(int i=0;i<NUM;i++){
pthread_create(&tid[i],NULL,thread,(void*)i);
}
//Sleep(2);
c[0].write(55); //broadcast signal
//Sleep(2);
c[1].write(44); //broadcast signal
for(int i=0;i<NUM;i++){
pthread_join(tid[i],NULL);
}
cout << "Hello world!" << endl;
return 0;
}
If I insert Sleep(2) in the main function, it works, but I do not want to wait a time but a synchronisation before calling pthread_broadcast.
I thought of a barrier, but pthread_cond_wait is blocking, right?
You need to read up on how condition variables are used. You also handled the integer arguments to your threads erroneously. Here is a fixed version, hopefully similar to what you wanted:
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#define NUM 4
#define SIZE 256
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_barrier_t barrier;
class cache{
int lv1;
public:
int write(int i) { lv1=i; }
const int val() { return lv1; }
};
cache c[NUM];
void *thread(void *arg)
{
int i = *(int*)arg;
for(;;) {
pthread_mutex_lock(&mutex);
// Check predicate, do not go to sleep if predicate is fulfilled
if (c[0].val() > 0 && c[1].val() > 0) {
cout << "Thread " << i << " leaving...\n";
pthread_mutex_unlock(&mutex);
return 0;
}
pthread_cond_wait(&cond, &mutex);
cout << "Thread wakeup: "<< i << endl;
// do some work
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t tid[NUM];
int arg[NUM];
for(int i=0; i<NUM; i++) {
arg[i] = i; // make a copy of i used by only one thread
pthread_create(&tid[i], NULL, thread,(void*)&arg[i]);
}
pthread_mutex_lock(&mutex);
c[0].write(55);
c[1].write(44);
pthread_mutex_unlock(&mutex);
pthread_cond_broadcast(&cond); // Signal all threads that predicate is fulfilled
for(int i=0; i<NUM; i++) {
pthread_join(tid[i],NULL);
cout << "Joined " << i << '\n';
}
cout << "Hello world!" << endl;
return 0;
}
Sequence how I think it is
This is how it is right now I think, I still need a way to synchronise, before I send the broadcast signal.
In that picture, the first pthread_broadcast comes too early.

C++: Control order of thread execution with mutex's and conditional variables

This question is a follow up for this question. I want threads to perform some work and pass handle to the next thread in order. When trying to execute the following code, I get
Unhandled exception at 0x0F7C1F5F (msvcp120d.dll) in ConsoleApplication9.exe: 0xC0000005 : Access violation reading location 0x00000004.
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>
std::mutex* m_pMutexs;
std::condition_variable* m_pCVs;
int m_pCurrentWorker;
void func(int i)
{
int cvCurrentInd = i;
std::mutex* pCurMutex = &m_pMutexs[cvCurrentInd];
std::condition_variable* pCuCV = (std::condition_variable*)(m_pCurrentWorker + i*sizeof(std::condition_variable));
std::unique_lock<std::mutex> lk(m_pMutexs[i]);
while (i != m_pCurrentWorker)
{
pCuCV->wait(lk);
}
std::cout << "entered thread " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(rand() % 10));
std::cout << "leaving thread " << std::this_thread::get_id() << std::endl;
m_pCurrentWorker++;
lk.unlock();
pCuCV->notify_one();
}
int _tmain(int argc, _TCHAR* argv[])
{
m_pMutexs = new std::mutex[3];
m_pCVs = new std::condition_variable[3];
m_pCurrentWorker = 0;
srand((unsigned int)time(0));
std::thread t1(func,0);
std::thread t2(func,1);
std::thread t3(func,2);
t1.join();
t2.join();
t3.join();
return 0;
}
Have no idea what you're trying to do but
You're casting integer to pointer?
std::condition_variable* pCuCV = (std::condition_variable*)(m_pCurrentWorker + i*sizeof(std::condition_variable));
I think you should write instead:
std::condition_variable* pCuCV = &m_pCVs[i];
The whole function could be something like this:
void func(int i)
{
std::mutex* pCurMutex = &m_pMutexs[i];
std::condition_variable* pCuCV = &m_pCVs[i];
std::unique_lock<std::mutex> lk(m_pMutexs[i]);
while (i != m_pCurrentWorker) {
pCuCV->wait(lk);
}
std::cout << "entered thread " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(rand() % 2));
std::cout << "leaving thread " << std::this_thread::get_id() << std::endl;
m_pCurrentWorker++;
lk.unlock();
if (m_pCurrentWorker > 2) {
return;
}
pCuCV = &m_pCVs[m_pCurrentWorker];
pCuCV->notify_one();
}
I did some further research and it seems that the code the original questions is not thread-safe