Run and break an infinite loop using two threads - c++

I am trying to run a loop until the user chooses to break out of it. Whether the user wants to run the function all night or for just a few seconds the loop should repeat until the user decides to stop it.
In researching solutions I came across using two threads to achieve this. The first thread would run the infinite loop while the second thread waited for user input. Upon receiving that input the second thread would terminate the first and then return.
How do I use the second thread to terminate the first?
#include <iostream>
#include <iomanip>
#include <ctime>
#include <thread>
#include <cstdlib>
#include <Windows.h>
using namespace std;
void timeCount()
{
time_t rawTime;
struct tm * timeinfo;
do
{
Sleep(500);
system("cls");
time(&rawTime);
cout << "Seconds passed this epoch:" << rawTime << endl << endl;
timeinfo = localtime(&rawTime);
cout << "The local time is:" << asctime(timeinfo) << endl;
timeinfo = gmtime(&rawTime);
cout << "The UTC time is :" << asctime(timeinfo) << endl;
} while (1 != 0);
};
void getStop()
{
system("pause");
};
void timeSince()
{
thread counter(timeCount);
thread stopper(getStop);
counter.detach();
stopper.join();
counter.~thread();
};

I usually use an atomic<int> or atomic<bool> to do it.
Thread function
void run( atomic<bool> & quit ) {
while (!quit) {
// Do some work.
}
}
Mainthread:
int main() {
// Just to show you can do this with more than 1 extra thread.
unsigned int nThreads = std::thread::hardware_concurrency();
std::atomic<bool> loopFlags[nThreads];
std::thread threads[nThreads];
// Start threads
for ( int i = 0; i < nThreads; i++) {
loopFlags[i] = false;
threads[i] = std::thread(run, std::ref(loopFlags[i]));
}
usleep(10000); // Sleep for a while or do something else.
// Shutdown other threads
for ( auto & flag : loopFlags ) {
flag = true;
}
// Wait for threads to actually finish.
for ( auto& thread : threads ) {
thread.join();
}
// Resume what you were doing.
}

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!)

boost::this_thread::sleep_for sleeping entire program

C++98 and Boost 1.54
I'm having trouble figuring out why using boost::this_thread::sleep_for is sleeping my entire program. The only time and place the Wait() function is called is inside this thread, and this thread's sole purpose is to read file names in a directory and trigger an upload.
But for some reason, when it reaches the boost::this_thread::sleep_for line in the Wait() function, it hangs there and sleeps all the other threads as well. I'm unsure what I am missing, so any help would be appreciated.
Code:
void Upload::ReadFileNames()
{
cout << "[DEBUG] ReadFileNames -> A " << endl;
Wait();
cout << "[DEBUG] ReadFileNames -> B " << endl;
// read filename stuff
}
void Upload::Wait()
{
typedef boost::chrono::duration<long, boost::ratio<60> > seconds;
int randomWaitTime = 0;
try{
randomWaitTime = lexical_cast<unsigned int>(getId());
randomWaitTime = randomWaitTime * 10;
}
catch ( const boost::bad_lexical_cast & e){
// cout << "[LOG] FileUpLoad : Wait : bad_lexical_cast : " << e.what() << endl ;
randomWaitTime = 0;
}
seconds testTimeToWait(randomWaitTime);
cout << "[DEBUG] Wait() -> A" << endl;
boost::this_thread::sleep_for(testTimeToWait);
cout << "[DEBUG] Wait() -> B" << endl;
cout << "RANDOM WAIT TIME = " << randomWaitTime << endl;
}
main.cpp
int main()
{
pthread_t threadA;
pthread_create(&threadA,NULL,threadAfn,NULL);
pthread_t threadB;
pthread_create(&threadB,NULL,threadBfn,NULL);
pthread_t Upload; // <--- Thread in question
pthread_create(&Upload,NULL,Uploadfn,NULL);
pthread_join(threadA,NULL);
pthread_join(threadB,NULL);
pthread_join(Upload,NULL); // <--- Thread in question
return 0;
}
Output
[DEBUG] ReadFileNames -> A
[DEBUG] Wait() -> A
// hangs here and rest of the threads are locked/slept as well?
it hangs there and sleeps all the other threads as well
No it doesn't. If it seems that way, that is because the other threads were already stuck or finished.
Look for things that block (mutex.lock, condition wait, IO operations, etc.) or check that the threads didn't exit.
Notes
Your seconds calculations is off. On my system, the following:
Live On Coliru
#include <boost/chrono.hpp>
#include <iostream>
int main() {
std::cout << boost::chrono::duration<long, boost::ratio<60> >(1)/boost::chrono::seconds(1) << std::endl;
}
Prints
60
So, what you named seconds is actually minutes. Just do this instead:
using boost::chrono::seconds;
int delay = std::strtoul(getId().c_str(), NULL, 10)*10;
sleep_for(seconds(delay));
Your random delay is only random if the getId return is. Using boost/random.hpp you can make it truly random, with good range control. E.g. to sleep between 1'000 and 3'000 ms:
int random_gen(int low, int high) { // not threadsafe
static boost::random_device rdev;
static boost::mt19937 prng(rdev);
return boost::uniform_int<>(low, high)(prng);
}
void Upload::Wait() {
int const ms_delay = random_gen(1000, 3000);
cout << "RANDOM WAIT TIME = " << ms_delay << endl;
sleep_for(milliseconds(ms_delay));
}
Note to seed using random_device as shown (so true random seed) you need to link the random library. Otherwise, you can "stoop" to a time-based seed:
static boost::mt19937 prng(std::time(NULL));
Here's a self-contained version of your code with the various suggestions applied, demonstrating that there is no deadlock/softlock:
Live On Coliru
#include <boost/asio.hpp>
#include <boost/chrono.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include <iostream>
#include <boost/random.hpp>
using boost::this_thread::sleep_for;
using boost::chrono::seconds;
using boost::chrono::milliseconds;
using boost::lexical_cast;
using std::cout;
using std::endl;
struct Upload {
std::string getId() const { return "42"; }
void Wait();
void ReadFileNames();
};
void Upload::ReadFileNames() {
cout << "[DEBUG] ReadFileNames -> A " << endl;
Wait();
cout << "[DEBUG] ReadFileNames -> B " << endl;
// read filename stuff
}
int random_gen(int low, int high) { // not threadsafe
static boost::mt19937 prng(std::time(NULL));
return boost::uniform_int<>(low, high)(prng);
}
void Upload::Wait() {
int const ms_delay = random_gen(1000, 3000);
cout << "RANDOM WAIT TIME = " << ms_delay << endl;
sleep_for(milliseconds(ms_delay));
}
void background(char const* name) {
// desync different background threads
sleep_for(milliseconds(boost::hash_value(name) % 1000));
for (int i=0; i<5; ++i) {
sleep_for(seconds(1));
std::clog << name << " " << i << std::endl;
}
}
void threadAfn() { background("thread A"); }
void threadBfn() { background("thread B"); }
void Uploadfn() {
Upload u;
u.ReadFileNames();
}
int main() {
boost::thread threadA(threadAfn);
boost::thread threadB(threadBfn);
boost::thread Upload(Uploadfn);
threadA.join();
threadB.join();
Upload.join();
}
Prints, e.g.:
[DEBUG] ReadFileNames -> A
RANDOM WAIT TIME = 1150
[DEBUG] ReadFileNames -> B
thread A 0
thread B 0
thread A 1
thread B 1
thread A 2
thread B 2
thread A 3
thread B 3
thread A 4
thread B 4

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

How to have one pthread continue while another thread is waiting on a semaphore in C++?

I am currently going over an example our professor gave us before our current assignment with semaphores and pthreading in C++. Currently, the entire program waits when one of the threads is blocked.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int account = 99;
bool sent = false;
int rate = 12;
int hours = 15;
sem_t s1;
sem_t s2;
//work thread
void *work(void*){
while(1){
sem_wait(&s1);
account += hours * rate;
cout << "Account: " << account << endl;
if(account >= 1000 && !sent){
sem_post(&s2);
sent = true;
}
sem_post(&s1);
pthread_exit(NULL);
}
}
void* buy(void*){
while(1){
sem_wait(&s2);
sem_wait(&s1);
account -= 1000;
sent = false;
cout << "iPhone bought!! Account: " << account << endl;
sem_post(&s1);
pthread_exit(NULL);
}
}
int main(){
pthread_t workt, buyt;
sem_init(&s1, 0, 1);
sem_init(&s2, 0, 0);
while(1){
pthread_create( &workt, NULL, work, NULL);
pthread_create( &buyt, NULL, buy, NULL);
pthread_join(workt, NULL);
pthread_join(buyt, NULL);
}
sem_close(&s1);
sem_close(&s2);
pthread_exit(NULL);
}
The program should run the 'work' thread continuously until enough is in the account (1000), then it will buy an iPhone. My code will run until it hits the sem_wait(s2) semaphore in the 'buy' thread, which blocks the thread as it should, but my entire program waits and does not run the 'work' thread again.
You're calling pthread_exit(NULL); on every iteration through your loop in work. Basically it's acting like there's no loop.
Maybe you mean something more like:
while(!sent){
sem_wait(&s1);
account += hours * rate;
cout << "Account: " << account << endl;
if(account >= 1000){
sem_post(&s2);
sent = true;
}
sem_post(&s1);
}
pthread_exit(NULL);

Still having race condition with boost::mutex

I am trying an example, which causes race condition to apply the mutex. However, even with the mutex, it still happens. What's wrong? Here is my code:
#include <iostream>
#include <boost/thread.hpp>
#include <vector>
using namespace std;
class Soldier
{
private:
boost::thread m_Thread;
public:
static int count , moneySpent;
static boost::mutex soldierMutex;
Soldier(){}
void start(int cost)
{
m_Thread = boost::thread(&Soldier::process, this,cost);
}
void process(int cost)
{
{
boost::mutex::scoped_lock lock(soldierMutex);
//soldierMutex.lock();
int tmp = count;
++tmp;
count = tmp;
tmp = moneySpent;
tmp += cost;
moneySpent = tmp;
// soldierMutex.unlock();
}
}
void join()
{
m_Thread.join();
}
};
int Soldier::count, Soldier::moneySpent;
boost::mutex Soldier::soldierMutex;
int main()
{
Soldier s1,s2,s3;
s1.start(20);
s2.start(30);
s3.start(40);
s1.join();
s2.join();
s3.join();
for (int i = 0; i < 100; ++i)
{
Soldier s;
s.start(30);
}
cout << "Total soldier: " << Soldier::count << '\n';
cout << "Money spent: " << Soldier::moneySpent << '\n';
}
It looks like you're not waiting for the threads started in the loop to finish. Change the loop to:
for (int i = 0; i < 100; ++i)
{
Soldier s;
s.start(30);
s.join();
}
edit to explain further
The problem you saw was that the values printed out were wrong, so you assumed there was a race condition in the threads. The race in fact was when you printed the values - they were printed while not all the threads had a chance to execute
Based on this and your previous post (were it does not seem you have read all the answers yet). What you are looking for is some form of synchronization point to prevent the main() thread from exiting the application (because when the main thread exits the application all the children thread die).
This is why you call join() all the time to prevent the main() thread from exiting until the thread has exited. As a result of your usage though your loop of threads is not parallel and each thread is run in sequence to completion (so no real point in using the thread).
Note: join() like in Java waits for the thread to complete. It does not start the thread.
A quick look at the boost documentation suggests what you are looking for is a thread group which will allow you to wait for all threads in the group to complete before exiting.
//No compiler so this is untested.
// But it should look something like this.
// Note 2: I have not used boost::threads much.
int main()
{
boost::thread_group group;
boost::ptr_vector<boost::thread> threads;
for(int loop = 0; loop < 100; ++loop)
{
// Create an object.
// With the function to make it start. Store the thread in a vector
threads.push_back(new boost::thread(<Function To Call>));
// Add the thread to the group.
group.add(threads.back());
}
// Make sure main does not exit before all the threads have completed.
group.join_all();
}
If we go back to your example and retrofit your Soldier class:
int main()
{
boost::thread batallion;
// Make all the soldiers part of a group.
// When you start the thread make the thread join the group.
Soldier s1(batallion);
Soldier s2(batallion);
Soldier s3(batallion);
s1.start(20);
s2.start(30);
s3.start(40);
// Create 100 soldiers outside the loo
std::vector<Soldier> lotsOfSoldiers;
lotsOfSoldiers.reserve(100); // to prevent reallocation in the loop.
// Because you are using objects we need to
// prevent copying of them after the thread starts.
for (int i = 0; i < 100; ++i)
{
lotsOfSoldiers.push_back(Solder(batallion));
lotsOfSoldiers.back().start(30);
}
// Print out values while threads are still running
// Note you may get here before any thread.
cout << "Total soldier: " << Soldier::count << '\n';
cout << "Money spent: " << Soldier::moneySpent << '\n';
batallion.join_all();
// Print out values when all threads are finished.
cout << "Total soldier: " << Soldier::count << '\n';
cout << "Money spent: " << Soldier::moneySpent << '\n';
}