Very simple method with QtConcurrentRun and mutex sometimes gives segmentation fault - c++

I want to know what is wrong with this code. Sometimes I get sementation fault, sometimes not. This is a problem that I have in a greater piece of software, the idea is that just one thread at the same time is executing the method MyClass::print. Even with this simple example, it fail with segmentation fault. What is wrong in the code? How I can solve the problem?
Thanks!
#include <iostream>
#include <ctime>
#include <QMutex>
#include <QtConcurrentRun>
class MyClass : QThread {
public:
void print(std::string str) {
mutex.lock();
std::cout << "In some thread: " << str << "\n";
mutex.unlock();
}
private:
QMutex mutex;
};
int main() {
MyClass myCl;
for(int i=0; i < 10; i++) {
QtConcurrent::run(&myCl, &MyClass::print,std::string("bla"));
}
}

You do not join your threads after the for cycle that spawns them.
Therefore, the main() function may end before all the threads have finished. This would make myCl go out of scope, and the threads would be trying to access an object that has been destroyed (in particular, its mutex variable). Which gives you Undefined Behavior.
Things should get better if you joined your threads before exiting from main() (or find any other way of not exiting from main() as long as any of the threads is still running).

Related

What happens when a thread is constructed, and how is the thread executed

I'm completely new to multithreading and have a little trouble understanding how multithreading actually works.
Let's consider the following example of code. The program simply takes file names as input and counts the number of lowercase letters in them.
#include <iostream>
#include <thread>
#include <mutex>
#include <memory>
#include <vector>
#include <string>
#include <fstream>
#include <ctype.h>
class LowercaseCounter{
public:
LowercaseCounter() :
total_count(0)
{}
void count_lowercase_letters(const std::string& filename)
{
int count = 0;
std::ifstream fin(filename);
char a;
while (fin >> a)
{
if (islower(a))
{
std::lock_guard<std::mutex> guard(m);
++total_count;
}
}
}
void print_num() const
{
std::lock_guard<std::mutex> guard(m);
std::cout << total_count << std::endl;
}
private:
int total_count;
mutable std::mutex m;
};
int main(){
std::vector<std::unique_ptr<std::thread>> threads;
LowercaseCounter counter;
std::string line;
while (std::cin >> line)
{
if (line == "exit")
break;
else if (line == "print")
counter.print_num(); //I think that this should print 0 every time it's called.
else
threads.emplace_back(new std::thread(&LowercaseCounter::count_lowercase_letters, counter, line));
}
for (auto& thread : threads)
thread->join();
}
Firstly I though that the output of counter.print_num() will print 0 as far as the threads are not 'joined' yet to execute the functions. However, It turns out that the program works correctly and the output of counter.print_num() is not 0. So I asked myself the following questions.
What actually happens when a thread is constructed?
If the program above works fine, then thread must be executed when is created, then what does std::thread::join method do?
If the thread is executed at the time of creation, then what's the point of using multithreading in this example?
Thanks in advance.
You seem to be under the impression that the program can only be running one thread at a time, and that it needs to interrupt whatever it's doing in order to execute the code of the thread. That's not the case.
You can think of a thread as a completely separate program that happens to share memory and resources with the program that created it. The function you pass as an argument is that program's 'main()` for every intent and purpose. In Linux, threads are literally separate processes, but as far as C++ is concerned, that's just an implementation detail.
So, in a modern operating system with preemptive multitasking, much like multiple programs can run at the same time, threads can also run at the same time. Note that I say can, it's up to the compiler and OS to decide when to give CPU time to each thread.
then what does std::thread::join method do?
It just waits until the thread is done.
So what would happen if I didn't call join() method for each one of threads
It would crash upon reaching the end of main() because attempting to exit the program without joining a non-detached thread is considered an error.
As you said, in c++ the thread is executed when it is created all std::thread::join does is wait for the thread to finish execution.
In your code all the threads will start executing simultaneously in the loop and then the main thread will wait for each thread to finish execution in the next loop.

Correct way to start a function object thread in C++?

I have this code so far :
#include <iostream>
#include <string>
#include <windows.h>
#include <iomanip>
#include <thread>
#include <chrono>
#include <atomic>
class test {
public:
thread t1;
test() : t1(&test::work, this) {
}
void work() {
while (true) {
cout << "in thread";
Sleep(1000);
}
}
};
int main()
{
test t;
while (true) {
cout << "in main" << endl;
Sleep(1000);
}
return 0;
}
Question 1: Is this how I'm suppose to create a thread in a class object for one function only after I initialize the object?
Question 2: I've seen people write atomic_bool and run(), is that necessary? and what is it for?
Question 3: do I need to delete or join the thread or do any kind of memory management?
Problem How can I create the thread somewhere else in the function of the objects other than the constructor? I have did this and it didn't work
void work() : t1(&test::work, this) {
while (true) {
cout << "in thread";
Sleep(1000);
}
}
Is this how I'm supposed to create a thread in a class object for one function only after I initialize the object?
It's one option. Another is t1([this]{ work(); }).
Relevant question: Start thread with member function
Be aware that, generally, the current instance (*this) may not be fully constructed when the thread starts executing.
I've seen people write atomic_bool and run(), is that necessary? and what is it for?
Don't know what run() is, but atomic variables are used for communication between threads via shared memory.
Do I need to delete or join the thread or do any kind of memory management?
No, you don't need any of these since your program never ends (at least normally).
How can I create the thread somewhere else in the function of the objects other than the constructor?
You can assign the thread member variable t1 a new value.
I would suggest reading some good book to learn such basics.

How can I syncronize these two threads properly?

I would like to synchronize different threads properly but so far I have only be able to write an inelegant solution. Can somebody kindly point out how I can improve the following code?
typedef void (*func)();
void thread(func func1, func func2, int& has_finished, int& id) {
has_finished--;
func1();
has_finished++;
while (has_finished != 0) std::cout << "thread " << id << " waiting\n";
std::cout << "thread" << id << "resuming\n";
func2();
}
int main() {
int has_finished(0), id_one(0), id_two(1);
std::thread t1(thread, fun, fun, std::ref(has_finished), std::ref(id_one));
std::thread t2(thread, fun, fun, std::ref(has_finished), std::ref(id_two));
t1.join();
t2.join();
};
The gist of the program is described by the function thread. The function is executed by two std::threads. The function accepts two long-running functions func1 and func2 and two references of ints as arguments. The threads should only invoke func2 after all threads exited func1. The argument has_finished is used to coordinate the different threads: Upon entering the function, has_arguments is zero. Then each std::thread decrements the value and invokes the long-running function func1. After having left func1, has_finished is incremented again. As long as this value is not at its original value of zero a thread waits. Then, each thread works on func2. The main function is shown at the end.
How can I coordinate the two threads better? I was thinking of using a std::mutex and std::condition_variable but could not figure out how to use them properly? Does somebody have any idea how I can improve the program?
Don't write this yourself. This kind of synchronization is known as a "latch" (or more generally a "barrier", and it's available through various libraries and through the C++ Concurrency TS. (It might also make it into C++20 in some form.)
For example, using a version from Boost:
#include <iostream>
#include <thread>
#include <boost/thread/latch.hpp>
void f(boost::latch& c) {
std::cout << "Doing work in round 1\n";
c.count_down_and_wait();
std::cout << "Doing work in round 2\n";
}
int main() {
boost::latch c(2);
std::thread t1(f, std::ref(c)), t2(f, std::ref(c));
t1.join();
t2.join();
}
The method you've chosen won't actually work and results in undefined behavior because of the race conditions. As you surmised, you need a condition variable.
Here is a Gate class demonstrating how to use a condition variable to implement a gate that waits for some number of threads to arrive at it before continuing:
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <sstream>
#include <utility>
#include <cassert>
struct Gate {
public:
explicit Gate(unsigned int count = 2) : count_(count) { } // How many threads need to reach the gate before it unlocks
Gate(Gate const &) = delete;
void operator =(Gate const &) = delete;
void wait_for_gate();
private:
int count_;
::std::mutex count_mutex_;
::std::condition_variable count_gate_;
};
void Gate::wait_for_gate()
{
::std::unique_lock<::std::mutex> guard(count_mutex_);
assert(count > 0); // Count being 0 here indicates an irrecoverable programming error.
--count_;
count_gate_.wait(guard, [this](){ return this-> count_ <= 0; });
guard.unlock();
count_gate_.notify_all();
}
void f1()
{
::std::ostringstream msg;
msg << "In f1 with thread " << ::std::this_thread::get_id() << '\n';
::std::cout << msg.str();
}
void f2()
{
::std::ostringstream msg;
msg << "In f2 with thread " << ::std::this_thread::get_id() << '\n';
::std::cout << msg.str();
}
void thread_func(Gate &gate)
{
f1();
gate.wait_for_gate();
f2();
}
int main()
{
Gate gate;
::std::thread t1{thread_func, ::std::ref(gate)};
::std::thread t2{thread_func, ::std::ref(gate)};
t1.join();
t2.join();
}
Hopefully the structure of this code looks enough like your code that you can understand what's going on here. From reading your code, it seems like you're looking for all threads to execute func1, then func2. You do not want func2 running while any thread is executing func1.
That can be thought of as a gate where all the threads are waiting to arrive at the 'finished func1' location before moving on to run func2.
I tested this code on my own local version of compiler explorer.
The main disadvantage of the latch in the other answer is that it is not yet standard C++. My Gate class is a simple implementation of the latch class mentioned in the other answer, and it is standard C++.
The basic way a condition variable works is that it unlocks a mutex, waits for a notify, then locks that mutex and tests the condition. If the condition is true, it continues without unlocking the mutex. If the condition is false, it starts over again.
So, after the condition variable says the condition is true, you have to do whatever you need to do, then unlock the mutex and notify everybody that you've done it.
The mutex here is guarding the shared count variable. Whenever you have a shared value you should guard it with a mutex so that no thread can see that value in an inconsistent state. The condition is that threads can wait for that count to reach 0, indicating that all threads have decremented the count variable.

Creating a class to store threads and calling them

Here is a simplified version of what I am trying to do:
#include <iostream>
#include <vector>
#include <thread>
#include <atomic>
class client {
private:
std::vector<std::thread> threads;
std::atomic<bool> running;
void main() {
while(running) {
std::cout << "main" << std::endl;
}
}
void render() {
while(running) {
std::cout << "render" << std::endl;
}
}
public:
client() {
running = true;
threads.push_back(std::thread(&client::main, this));
threads.push_back(std::thread(&client::render, this));
}
~client() {
running = false;
for(auto& th : threads) th.join();
};
};
int main() {
client c;
std::string inputString;
getline(std::cin, inputString);
return 0;
}
(Note: code has been changed since question was written)
What I am trying to do is create a class that holds threads for the main loop(of the class), rendering, and a couple other things. However I cannot get this simplified version to work. I have tried using mutex to lock and unlock the threads, but didn't seem to help any. I do not know why it is not working, but I suspect that it is a result of the use of this in threads.push_back(std::thread(this->main, this));.
The current structure of the code doesn't have to remain... The only requirement is that uses one of it's own member functions as a thread (and that, that thread is stored in the class). I am not sure if this requires two classes or if my attempt to do it in one class was the correct approach. I have seen many examples of creating an object, and then calling a member that creates threads. I am trying to avoid this and instead create the threads within the constructor.
The problem here is that you do not wait for the threads to end. In main you create c. This then spawns the threads. The next thing to happen is to return which destroys c. When c is destroyed it destroys its members. Now when a thread is destroyed if it has not been joined or detached then std::terminate is called and the program ends
What you need to do is in the destructor, set running to false and then call join on both the threads. This will stop the loop in each thread and allow c to be destructed correctly.
Doing this however brings up another issue. running is not an atomic variable so writing to it while threads are reading it is undefined behavior. We can fin that though by changing running to a std::atomic<bool> which provides synchronization.
I also had to make a change to the thread construction. When you want to use a member function the syntax should be
std::thread(&class_name::function_name, pointer_to_instance_of_class_name, function_parameters)
so in this case it would be
threads.push_back(std::thread(&client::main, this));
threads.push_back(std::thread(&client::render, this));

Synchronise two threads passing events between each other

I am new to windows c++ programming. Please see the below code where I want to make the two threads synchronized. The first thread should print "Hello" then pass the control/event to the second thread. Not sure how to do it. As of now I am using Sleep(1000). But if I dont use Sleep it result into undefined behavior. Please help...
#include <windows.h>
#include <process.h>
#include <iostream>
void thread1(void*);
void thread2(void*);
int main(int argc, char **argv) {
_beginthread(&thread1,0,(void*)0);
_beginthread(&thread2,0,(void*)0);
Sleep(1000);
}
void thread1(void*)
{
std::cout<<"Hello "<<std::endl;
}
void thread2(void*)
{
std::cout<<"World"<<std::endl;
}
The problem is the question you are asking really doesn't make sense. Multiple threads are designed to run at the same time and you're trying to play a game of pass the buck from one thread to another to get sequential serialised behavoir. Its like taking a really complicated tool and ask how it solves what is normally a really easy question.
However, multithreading is a really important topic to learn so I'll try to answer what you need to the best of my ability.
Firstly, I'd recommend using the new, standard C++11 functions and libraries. For windows, you can download Visual Studio 2012 Express Edition to play about with.
With this you can use std::thread, std::mutex and a lot [but not all] of the other C++11 goodies (like std::condition_variable).
To solve your problem you really need a condition variable. This lets you signal to another thread that something is ready for them:
#include <iostream>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <thread>
static std::atomic<bool> ready;
static std::mutex lock;
static std::condition_variable cv;
// ThreadOne immediately prints Hello then 'notifies' the condition variable
void ThreadOne()
{
std::cout << "Hello ";
ready = true;
cv.notify_one();
}
// ThreadTwo waits for someone to 'notify' the condition variable then prints 'World'
// Note: The 'cv.wait' must be in a loop as spurious wake-ups for condition_variables are allowed
void ThreadTwo()
{
while(true)
{
std::unique_lock<std::mutex> stackLock(lock);
cv.wait(stackLock);
if(ready) break;
}
std::cout << "World!" << std::endl;
}
// Main just kicks off two 'std::thread's. We must wait for both those threads
// to finish before we can return from main. 'join' does this - its the std
// equivalent of calling 'WaitForSingleObject' on the thread handle. its necessary
// to call join as the standard says so - but the underlying reason is that
// when main returns global destructors will start running. If your thread is also
// running at this critical time then it will possibly access global objects which
// are destructing or have destructed which is *bad*
int main(int argc, char **argv)
{
std::thread t1([](){ThreadOne();});
std::thread t2([](){ThreadTwo();});
t1.join();
t2.join();
}
Here is the simplified version to handle your situation.
You are creating 2 threads to call 2 different function.
Ideally thread synchronization is used to serialize same code between threads but in your case it is not the need. You are trying to serialize 2 threads which are no way related to one another.
Any how you can wait for each thread to finish by not making async call.
#include <windows.h>
#include <process.h>
#include <iostream>
#include<mutex>
using namespace std;
void thread1(void*);
void thread2(void*);
int main(int argc, char **argv) {
HANDLE h1 = (HANDLE)_beginthread(&thread1,0,(void*)0);
WaitForSingleObject(h1,INFINITE);
HANDLE h2 = (HANDLE)_beginthread(&thread2,0,(void*)0);
WaitForSingleObject(h2,INFINITE);
}
void thread1(void*)
{
std::cout<<"Hello "<<std::endl;
}
void thread2(void*)
{
std::cout<<"World"<<std::endl;
}
You can group both beginthread in single function and call that function in while loop if you want to print multiple times.
void fun()
{
HANDLE h1 = (HANDLE)_beginthread(&thread1,0,(void*)0);
WaitForSingleObject(h1,INFINITE);
HANDLE h2 = (HANDLE)_beginthread(&thread2,0,(void*)0);
WaitForSingleObject(h2,INFINITE);
}