I'm new to C++ and am trying to have two threads run:
i) Thread that keeps looping until an atomic bool is flipped.
ii) A thread that polls for input from keyboard and flips the atomic bool.
I seem to be unable to get std::cin.get() to react to an input unless it is assigned its' own thread (like below). Why? Would it not then be set from the parent main thread?
#include <iostream>
#include <iomanip> // To set decimal places.
#include <thread> //std::thread
#include <atomic> //for atomic boolean shared between threads.
#include <math.h>
#define USE_MATH_DEFINES //For PI
std::atomic<bool> keepRunning(false); //set to false to avoid compiler optimising away.
void loop(){
int t = 1;
while(!keepRunning.load(std::memory_order_acquire)) //lower cost than directly polling atomic bool?
{
//Write sine wave output to console.
std::cout << std::setprecision(3) << sin(M_PI * 2 * t/100) << std::endl;
(t<101)? t++ : t = 1;
}
}
//This works, as opposed to stopping in main.
void countSafe(){
int j = 1;
while (j<1E7)
{
j++;
}
keepRunning.store(true, std::memory_order_release); //ends the loop thread.
}
int main(){
std::thread first (loop); //start the loop thread
std::thread second (countSafe); //start the countSafe thread. Without this it doesn't work.
//Why does polling for std::cin.get() here not work?
//std::cin.get(); //wait for key press. puts in buffer..?
//keepRunning.store(true, std::memory_order_release); //Set stop to true.
second.join(); //pause to join.
first.join(); //pause to join
return 0;
}
I'm not quite sure what your problem is, but use of cin.get() might be part of it. Let's simplify with this code:
#include <iostream>
using namespace std;
int main(int, char **) {
cout << "Type something: ";
cin.get();
cout << "Done.\n";
}
Try that code and run it. Then type a single character. Chances are that the code won't recognize it. And you can type all you want until you hit return.
This is complicated, but your program doesn't actually receive the characters until you hit return unless you play other games. Like I said, it's complicated.
It's possible behavior is different on Windows, but this is the behavior on Mac and Linux.
So is it "not working" because you tried typing a space but you really need to use Return?
Related
I'm working on simple cancellation mechanism. But I have found problem with waiting for timeout on condition variable.
Lets consider the sample program from:
https://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/
It looks like this sample is broken. If someone would provide the data very fast then the program would go into infinite loop. To visualize it I did little modification to the sample program:
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
using namespace std::chrono_literals;
std::condition_variable cv;
int value = -1;
void compute() {
value = 0;;
cv.notify_one();
}
int main()
{
std::thread th(compute);
std::this_thread::sleep_for(1s);
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while (cv.wait_for(lck, std::chrono::seconds(1)) == std::cv_status::timeout) {
std::cout << '.' << std::endl;
}
std::cout << "You entered: " << value << '\n';
th.join();
return 0;
}
As I can't type as fast I just set the value to 0 and execute notify_one.
On the main thread I simulate simple delay. sleep_for(1s).
Finally the program does not see the notify_one and loops infinitely.
The output is: .....
My question is how to implement it correctly ?
I would like to know also if the waiting was stopped by timeout.
If the notify happens before the wait then it indeed gets "lost".
Most usage of CVs also require a flag of some sort which should be checked in the predicate. You already have this flag - value. Just use this as a predicate:
EDIT: Removed wrong code.
Note that as a separate matter you should protect the writing to value with your mutex or you're likely to hit UB. Which means you need to make your mutex global along with the CV/Flag.
Better way:
auto endTime = std::chrono::now() + std::chrono::seconds(1);
while(flag != 0)
{
auto res = cv.wait_until(lck, endTime);
if (res == std::cv_status::timeout)
{
// Add Timeout logic here
break;
}
}
Code:
#include <iostream>
#include <future>
#include <queue>
#include <boost/thread/thread.hpp>
boost::mutex mtx;
std::queue<std::string>ev;
void t_1(){
while(true){
mtx.lock();
if(ev.size() > 0){
std::cout << ev.front();
ev.pop();
}
mtx.unlock();
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
}
}
void t_2(){
int x = 0;
while(true){
x++;
mtx.lock();
ev.push("new event");
mtx.unlock();
boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
}
}
void t_3(){
while(true){
std::cout << 3;
}
}
int main(int argc, const char * argv[]) {
// insert code here...
boost::thread t1(t_1);
boost::thread t2(t_2);
//boost::thread t3(t_3);
t1.join();
t2.join();
while(true){
std::cout << "anyone there";
}
//t3.join();
return 0;
}
I was messing around with the boost library, and wanted to make an event checker using threads and mutexes. For some reason there is no output, even on the main thread when it should print "anyone there." I am using Mac OSX and Xcode. THe program compiles and runs just fine.
As already mentioned by #krzaq your main loop does not print anything because join waits for the termination of the thread, which will never happen due to the endless loops in t_1 and t_2.
As for your t_1 output: You have no newline in your output. Typically the output buffer is flushed only on a newline, which means that you will not see the output flushed to your terminal until you either print a newline or the buffer is filled up.
Try this:
std::cout << ev.front() << "\n";
Your threads never finish, and you join() them (that is, wait for them to finish) before the printing loop in the main thread.
t1.join(); // the main thread never gets past this point
I am getting into threading in C++ and was going some testing and got this error.
Here is my code:
#include <iostream>
#include <thread>
#include <unordered_map>
#include <string>
#include <vector>
using namespace std;
static vector<string> thisVector;
void thread1() {
for (int i = 0; i < 400; i++){
thisVector.push_back(to_string(i));
}
cout << "Finished 1" << endl;
return;
}
void thread2() {
for (int i = 0; i < 400; i++){
thisVector.push_back(to_string(i));
}
cout << "Finished 2" << endl;
return;
}
int main(int argc, const char * argv[]) {
thread first(thread1);
thread second(thread2);
first.join();
second.join();
cout << "done threading" << endl;
cout << thisVector.size() << endl;
return 0;
}
The weird thing is, sometimes I get the correct output, so 800. Sometimes I get a number slightly lower than that for I don't know what reason??? And sometimes I get the following error:
malloc: *** error for object 0x100400028: pointer being freed was not allocated
Any help would be greatly appreciated!
Thanks
A std::vector is not thread safe. You have two execution threads modifying the same std::vector concurrently. Operations on a std::vector should, in this case, be protected by a mutex.
The result of this is undefined behavior. As you've observed, sometimes it might work, sometimes wrong results get produced but the program completes successfully, sometimes the program crashes. This is what "undefined behavior" means.
It is worth reading The C++ Programming Language, it covers subjects of interest like : threads, tasks, but also at higher conceptual level future/promise, packaged_task, async.
In your case, you don't only deal with concurrency. You have to deal with shared data of concurrent threads. The way you programmed it does not guarantee any order of execution. That is why you get those strange results.
The error message you mentioned is likely to be because of concurrent access to the shared vector and it says what is wrong: a pointer is being freed (delete), but was not allocated beforehand. You don't see the pointer, it's an internal member of vector.
Your solution is to use a mutex to make sure that whenever a data is pushed back into the vector it does not get interrupted by the other concurrent thread and finishes appropriately, so that the next push_back starts only when the previous one has finished.
You can use a global variable for mutex. Then you need to deal appropriately with locking/unlocking, i.e. you must say when to acquire a mutex (before push_back) and when to release it (after push_back). Since you use only one mutex this should be fairly simple and should work.
You can try something like this:
#include <iostream>
#include <thread>
#include <unordered_map>
#include <string>
#include <vector>
using namespace std;
static vector<string> thisVector;
//Global MUTEX
mutex mv;
//
void thread1() {
for (int i = 0; i < 400; i++){
//Lock before and unlock after push back
mv.lock();
thisVector.push_back(to_string(i));
mv.unlock();
}
cout << "Finished 1" << endl;
return;
}
void thread2() {
for (int i = 0; i < 400; i++){
mv.lock();
thisVector.push_back(to_string(i));
mv.unlock();
}
cout << "Finished 2" << endl;
return;
}
int main(int argc, const char * argv[]) {
thread first(thread1);
thread second(thread2);
first.join();
second.join();
cout << "done threading" << endl;
cout << thisVector.size() << endl;
return 0;
}
Is there a way to break out of an infinite loop while it's running without using Ctrl + C? I would like to implement such a method in other programs. Like in this example program:
#include <iostream>
int main()
{
int x = 0;
for(;;)
cout << x;
}
is there a way to keep the for loop going but break it with some key at any time. I should also explain I understand using break;, but I want the loop to keep going. If I use a break condition like this, the for-loop would stop and wait for a response.
#include <iostream>
int main()
{
int x = 0;
for(;;)
{
cout << x;
if(getch()=='n')
break;
}
}
Find some condition that you wish to break out of the loop when encountered then use the break keyword:
#include <iostream>
int main()
{
int x = 0;
for(;;)
cout << x;
if(/* break condition*/){
break;
}
}
There's nothing stopping you from implementing the break condition by detecting a particular keyboard input from a user.
EDIT: From your edited question it appears you want to have loop continue running all the time and not stopping waiting for user input. The only way I can think of doing this is to spawn a new thread that listens for user input that alters a variable that gets detected in the break condition of your main thread.
If you have access to c++11 and the new thread library you could do something like this:
#include <iostream>
#include <thread>
bool break_condition = false;
void looper(){
for(;;){
std::cout << "loop running" << std::endl;
if(break_condition){
break;
}
}
}
void user_input(){
if(std::cin.get()=='n'){
break_condition = true;
}
}
int main(){
//create a thread for the loop and one for listening for input
std::thread loop_thread(looper);
std::thread user_input_thread(user_input);
//synchronize threads
loop_thread.join();
user_input_thread.join();
std::cout << "loop successfully broken out of" << std::endl;
return 0;
}
If you do decide to take a threading approach be careful as there's issues in multithreaded code that don't exist in single threaded code and they can sometimes be really nasty.
You are looking for continue I think
#include <iostream>
int main()
{
int x = 0;
for(;;)
{
cout << x;
if(getch()=='n')
continue;
}
}
Hey - I'm having an odd problem with a little toy program I've written, to try out threads.
This is my code:
#include <pthread.h>
#include <iostream>
using std::cout;
using std::endl;
void *threadFunc(void *arg) {
cout << "I am a thread. Hear me roar." << endl;
pthread_exit(NULL);
}
int main() {
cout << "Hello there." << endl;
int returnValue;
pthread_t myThread;
returnValue = pthread_create(&myThread, NULL, threadFunc, NULL);
if (returnValue != 0) {
cout << "Couldn't create thread! Whoops." << endl;
return -1;
}
return 0;
}
With the first cout in main not commented out, the thread prints fine.
However, without it, the thread doesn't print anything at all.
Any help?
Try this:
#include <pthread.h>
#include <iostream>
using std::cout;
using std::endl;
void *threadFunc(void *arg) {
cout << "I am a thread. Hear me roar." << endl;
pthread_exit(NULL);
}
int main() {
//cout << "Hello there." << endl;
int returnValue;
pthread_t myThread;
returnValue = pthread_create(&myThread, NULL, threadFunc, NULL);
if (returnValue != 0) {
cout << "Couldn't create thread! Whoops." << endl;
return -1;
}
pthread_join( myThread, NULL);
return 0;
}
The difference between my code and yours is one line - pthread join. This suspends the main thread until the sub-thread has had chance to complete its actions.
In your code, execution reaches the first cout and it's processed. Then, you split off another thread and the main thread carries on until the end, which may or may not be reached before the secondary thread is tidied up. That's where the odd behaviour comes in - what you are experiencing is the case where the main program finishes before the sub-thread has had a chance to, so the program has "returned" and the whole lot is cleaned up by the kernel.
It's a race condition that allows the program to work when the main loop takes a little while to run. Your program is exiting before the thread even has a chance to run.
You should wait for the thread to complete (see pthread_join) before returning from main().
The fact that it works in one case is pure luck. You have a timing issue, which is your program is exiting before your thread does it's work.
When main() exits all your threads will die. You need some sort of waiting in place to give the other thread time to run before main() exits. Try adding a cin in main() after you create the worker thread and see what happens.
Ultimately you'll want some sort of run-loop and messaging/eventing to communicate between threads.
-jeff
Try adding a pthread_exit(NULL); at the end of main, before the return 0. I suspect that the problem is your main returns and the process exits before the thread has a chance to print. Printing from main might be somehow modifying the timing such that the thread does get a chance to print -- but that's is just sheer luck. You need to ensure that main doesn't return until all of your threads are finished doing their work. Calling pthread_exit from main allows other threads to continue running until they too have called pthread_exit.