How can I execute two threads asynchronously using boost? - c++

I have the book "beyond the C++ standard library" and there are no examples of multithreading using boost. Would somebody be kind enough to show me a simple example where two threads are executed using boost- lets say asynchronously?

This is my minimal Boost threading example.
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
void ThreadFunction()
{
int counter = 0;
for(;;)
{
cout << "thread iteration " << ++counter << " Press Enter to stop" << endl;
try
{
// Sleep and check for interrupt.
// To check for interrupt without sleep,
// use boost::this_thread::interruption_point()
// which also throws boost::thread_interrupted
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
}
catch(boost::thread_interrupted&)
{
cout << "Thread is stopped" << endl;
return;
}
}
}
int main()
{
// Start thread
boost::thread t(&ThreadFunction);
// Wait for Enter
char ch;
cin.get(ch);
// Ask thread to stop
t.interrupt();
// Join - wait when thread actually exits
t.join();
cout << "main: thread ended" << endl;
return 0;
}

Related

Executing a non blocking thread in C++

I have a main program, this main program executes a thread that perform an action until the user triggers a stop. The problem that I have is if I add th.join() the main program won't continue until the thread finishes. And If there is no .join() the program crashs.
#include <iostream>
#include <thread>
#include <optional>
static bool s_finished = false;
using namespace std::literals::chrono_literals;
void SendData(int id)
{
std::cout << "Working thread: " << id << std::endl;
std::cout << "Started thread id: " << std::this_thread::get_id() << std::endl;
while (!s_finished)
{
std::cout << "Working\n";
std::this_thread::sleep_for(1s);
}
}
void startRecording(std::optional<int> t)
{
std::thread th1 (SendData, 1);
//th1.join();
std::cout << "[startRecording] Other Task" << std::endl;
}
void stopRecording()
{
s_finished = true;
std::cout << "[stopRecording] Other Task" << std::endl;
}
int main()
{
std::cout << "Start Program!" << std::endl;
startRecording();
std::this_thread::sleep_for(5s);
stopRecording();
return 0;
}
How can I do this?
Joining a thread will cause the program to stop until that thread is finished, and that's why the program blocks. We have to call join() eventually so that all child threads finish before the program exits, but we shouldn't call join until we need the child thread to be finished.
The simplest way to get the program to work is to return the thread from startRecording, so that we have control of it inside main. Then, we join the thread at the end of main, after we call stopRecording.
#include <iostream>
#include <thread>
#include <optional>
#include <atomic>
// (1) This needs to be atomic to avoid data races
std::atomic<bool> s_finished { false };
using namespace std::literals::chrono_literals;
void SendData(int id)
{
std::cout << "Working thread: " << id << std::endl;
std::cout << "Started thread id: " << std::this_thread::get_id() << std::endl;
while (!s_finished)
{
std::cout << "Working\n";
std::this_thread::sleep_for(1s);
}
}
std::thread startRecording(std::optional<int> t)
{
std::thread th1 (SendData, 1);
std::cout << "[startRecording] Other Task" << std::endl;
// (2) We return the thread so we can join it in main:
return th1;
}
void stopRecording()
{
s_finished = true;
std::cout << "[stopRecording] Other Task" << std::endl;
}
int main()
{
std::cout << "Start Program!" << std::endl;
// (3) We save the thread to a variable named 'worker'
// so we can join it later. I also added an input to startRecording b/c it needed one
std::thread worker = startRecording(std::optional<int>{1});
std::this_thread::sleep_for(5s);
stopRecording();
// (4) Join here, at the end
worker.join();
return 0;
}
Now, the program prints the expected output, then exits without problems:
Start Program!
[startRecording] Other Task
Working thread: 1
Started thread id: 139985258444544
Working
Working
Working
Working
Working
[stopRecording] Other Task
I marked my changes with (1), (2), (3), and (4) in the comments of the code. They're pretty small, and if you have questions about any of them I can provide additional explanation!
Addendum - using global variables when the signature of startRecording can't be changed
In general, it's best to avoid global variables, but I know it's not always possible to do so. if startRecording's signature can't be changed, we can't return a thread, so the thread has to be accessed globally. Here's how to do that:
#include <iostream>
#include <thread>
#include <optional>
#include <atomic>
// (1) This needs to be atomic to avoid data races
std::atomic<bool> s_finished { false };
// (2) we initialize this in startRecording
std::thread worker;
using namespace std::literals::chrono_literals;
void SendData(int id)
{
std::cout << "Working thread: " << id << std::endl;
std::cout << "Started thread id: " << std::this_thread::get_id() << std::endl;
while (!s_finished)
{
std::cout << "Working\n";
std::this_thread::sleep_for(1s);
}
}
void startRecording(std::optional<int> t)
{
// (3) worker gets initialized, and thread starts
worker = std::thread(SendData, 1);
std::cout << "[startRecording] Other Task" << std::endl;
}
void stopRecording()
{
s_finished = true;
std::cout << "[stopRecording] Other Task" << std::endl;
}
int main()
{
std::cout << "Start Program!" << std::endl;
startRecording(std::optional<int>{1});
std::this_thread::sleep_for(5s);
stopRecording();
// (4) Join here, at the end
worker.join();
return 0;
}

Optimal infinite C++ while loop with interval

I have a question about the correctness of my code.
I'm making a app which is run as a daemon, it do some code in interval, code looks:
#include <iostream>
#include <thread>
using namespace std;
int main() {
thread([=]() {
while (true) {
try {
cout << "log" << endl;
this_thread::sleep_for(chrono::milliseconds(3000));
}
catch (...) {
cout << "Some errors here :/" << endl;
}
}
}).detach();
while (true);
}
I'm worried weather this code is optimal, because in top I can see, that this program uses about 80% of the CPU.
Can I correct something?
Is my code equivalent to this one:
https://stackoverflow.com/a/21058232/5334833?
It appears that while(true); is UB.
You might just get rid of thread BTW:
int main() {
while (true) {
try {
std::cout << "log" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
}
catch (...) {
std::cout << "Some errors here :/" << std::endl;
}
}
}
while(true); will cause your main thread to continuously loop and use 100% of a single CPU.
Assuming you are on Linux you can just call pause() instead which will suspend your main thread until a signal arrives.
As you aren't actually using your main thread is there a reason you are spawning a new thread at all? Can you just do your work in the main thread?

C++ multi thread programming with timer

I am new to multi thread programming, so this question might seem a little silly, but I really need to work this out so I can apply it to my project (which is way more complicated).
Follow is my code, I am trying to have 2 threads (parent and child) to update the same shared timer as they execute and stop when the timer reaches a specific limit.
But when I compile and execute this follow piece of code, there are 2 different outcomes: 1. child prints "done by child at 200000" but the program does not exit; 2. after child prints "done by child at 200000" and exits, parent keeps executing, prints a couple of dozen lines of "parent doing work" and "parent at 190000", then prints "done by parent at 200000" and the program exits properly.
The behavior I want is for whichever thread that updates the timer, hits the limit and exits, the other thread should stop executing and exit as well. I think I might be missing something trivial here, but I've tried changing the code in many ways and nothing I tried seem to work. Any help will be much appreciated :)
#include <iostream>
#include <unistd.h>
#include <mutex>
#include <time.h>
using namespace std;
mutex mtx;
int main () {
int rc;
volatile int done = 0;
clock_t start = clock();
volatile clock_t now;
rc = fork();
if (rc == 0) { //child
while (true) {
cout << "child doing work" << endl;
mtx.lock();
now = clock() - start;
if (done) {
mtx.unlock();
break;
}
if (now >= 200000 && !done) {
done = 1;
cout << "done by child at " << now << endl;
mtx.unlock();
break;
}
cout << "child at " << now << endl;
mtx.unlock();
}
_exit(0);
}
else { // parent
while (true) {
cout << "parent doing work" << endl;
mtx.lock();
now = clock() - start;
if (done) {
mtx.unlock();
break;
}
if (now >= 200000 && !done) {
done = 1;
cout << "done by parent at " << now << endl;
mtx.unlock();
break;
}
cout << "parent at " << now << endl;
mtx.unlock();
}
}
return 0;
}
Multi-processes
Your code is multi-processes and not multi-threading: fork() will create a new separate process by duplicating the calling process.
The consequence: At the moment of the duplication, all the variables contain the same value in both processes. But each process has its own copy, so a variable modified in the parent will not be updated in the child's address space an vice-versa.
If you want to share variables between processes, you should have a look at this SO question
Multithread
For real multithreading, you should use std::thread. And forget about volatile, because it's not thread safe. Use <atomic> instead, as explained in this awesome video.
Here a first try:
#include <iostream>
#include <mutex>
#include <thread>
#include <atomic>
#include <time.h>
using namespace std;
void child (atomic<int>& done, atomic<clock_t>& now, clock_t start)
{
while (!done) {
cout << "child doing work" << endl;
now = clock() - start;
if (now >= 2000 && !done) {
done = 1;
cout << "done by child at " << now << endl;
}
cout << "child at " << now << endl;
this_thread::yield();
}
}
void parent (atomic<int>& done, atomic<clock_t>& now, clock_t start)
{
while (!done) {
cout << "parent doing work" << endl;
now = clock() - start;
if (now >= 2000 && !done) {
done = 1;
cout << "done by parent at " << now << endl;
}
cout << "parent at " << now << endl;
this_thread::yield();
}
}
int main () {
atomic<int> done{0};
clock_t start = clock();
atomic<clock_t> now;
thread t(child, std::ref(done), std::ref(now), start); // attention, without ref, you get clones
parent (done, now, start);
t.join();
return 0;
}
Note that you don't need to protect atomic accesses with a mutex, and that if you want to do, lock_guard would be recommended alternative.
This example is of course rather weak, because if you test an atomic variable if the if-condition, it's value might already have changed when entering the if-block. This doesn't cause a problem in your logic where "done" means "done". But if you'd need a more cauthious approach,
compare_exchange_weak() or compare_exchange_strong() could help further.

cancelling std::thread using native_handle() + pthread_cancel()

I am converting a previous thread wrapper around pthreads to std::thread.
However c++11 does not have any way to cancel the thread. I REQUIRE, nonetheless, to cancel threads since they may be performing a very lengthy task inside an external library.
I was considering using the native_handle that gives me pthread_id in my platform. I'm using gcc 4.7 in Linux (Ubuntu 12.10). The idea would be:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int main(int argc, char **argv) {
cout << "Hello, world!" << endl;
auto lambda = []() {
cout << "ID: "<<pthread_self() <<endl;
while (true) {
cout << "Hello" << endl;
this_thread::sleep_for(chrono::seconds(2));
}
};
pthread_t id;
{
std::thread th(lambda);
this_thread::sleep_for(chrono::seconds(1));
id = th.native_handle();
cout << id << endl;
th.detach();
}
cout << "cancelling ID: "<< id << endl;
pthread_cancel(id);
cout << "cancelled: "<< id << endl;
return 0;
}
The thread is canceled by an exception thrown by pthreads.
My question is:
Will there be any problem with this approach (besides not being portable)?
No, I don't think that you will not have additional problems than:
not being portable
having to program _very_very_ carefully that all objects of the cancelled thread are destroyed...
For example, the Standard says that when a thread ends variables will be destroyed. If you cancel a thread this will be much harder for the compiler, if not impossible.
I would, therefore recommend not to cancel a thread if you can somehow avoid it. Write a standard polling-loop, use a condition variable, listen on a signal to interrupt reads and so on -- and end the thread regularly.

Synchronization in Pthread C++

I've read about synchronized thread in Posix threads tutorial. They say that function pthread_join is used for waiting thread until it stops. But why doesn't this idea work in that case?
Here is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int a[5];
void* thread(void *params)
{
cout << "Hello, thread!" << endl;
cout << "How are you, thread? " << endl;
cout << "I'm glad to see you, thread! " << endl;
}
void* thread2(void *params)
{
cout << "Hello, second thread!" << endl;
cout << "How are you, second thread? " << endl;
cout << "I'm glad to see you, second thread! " << endl;
// for (;;);
}
int main()
{
pthread_t pt1, pt2;
int iret = pthread_create(&pt1, NULL, thread, NULL);
int iret2 = pthread_create(&pt2, NULL, thread2, NULL);
cout << "Hello, world!" << endl;
pthread_join(pt1, NULL);
cout << "Hello, middle!" << endl;
pthread_join(pt2, NULL);
cout << "The END" << endl;
return 0;
}
Threads are executed asynchronously, as someone already mentioned in answer to question you linked. Thread execution starts right after you create() it. So, at this point:
int iret = pthread_create(&pt1, NULL, thread, NULL);
thread() is already executing in another thread, possibly on another core (but it doesn't really matter). If you add a for (;;); in your main() right after that, you will still see thread message being printed to console.
You also misunderstood what join() does. It waits for thread termination; as your threads don't do any real work, they will (most probably) reach their ends and terminate way before you call join() on them. Once again: join() doesn't start execution of thread in given place, but waits for it to terminate (or just returns, if it's already terminated).