This is my simplified class which is used to detect problem in my full program:
SimpleThread.h
class SimpleThread {
public:
SimpleThread();
~SimpleThread();
void startThread();
void threadFn();
private:
SerialPort mySerial;
std::thread myThread;
int count;
std::mutex myMutex;
};
SimpleThread.cpp
SimpleThread::SimpleThread(): mySerial("/dev/ttyACM0") {
count = 0;
mySerial.Open(//Here correct params//);
}
SimpleThread::~SimpleThread() {}
void SimpleThread::threadFn() {
char cp;
while (true) {
cp = mySerial.ReadByte(0);
std::cout << count++ << " " << cp << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void SimpleThread::startThread() {
myThread = std::thread(&SimpleThread::threadFn, this);
myThread.detach();
}
main.cpp
int main() {
SimpleThread thr;
thr.startThread();
while (true) {
std::cout << "Waiting 5 seconds" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
The main idea of my example: I am using class member function as thread function to read data from opened serial port. There are no problems in using this class without reading from serial: main loop prints message every 5 seconds while thread loop (function inside class) prints 5 numbers.
Now I want to implement reading from serial port while my main loop is going to do something else. To read/write in serial I took this not so up-to-date serial library.
In this case class starts to work unexpected for me: main loop (which should show message every 5 seconds) shows its message faster then thread loop (about 40 times while 1 second). This code works wrong cause main loop prints message 40 times at 1 second (after read byte) despite sleep function.
So my question is: where is the root of my problem? Should I use another serial library or there are some features connected with interruptions which I dont know about?
Edit: If I use next loop for reading with checking if data is available, the main loop prints after every read byte. Looks like reading byte in thread loop interrupts main loop and cancels sleeping.
if ( mySerial.IsDataAvailable() ) {
cp = mySerial.ReadByte(0);
std::cout << count++ << " " << cp << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
Edit 2: Moreover, I tested just opening the Serial but without reading from Serial in loop (with changed pause in thread loop on two seconds)
if ( mySerial.IsDataAvailable() ) {
std::cout << count++ << " " << cp << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
}
In this case main loop prints every one second. There is no problem only if Serial port is not opened.
libserial uses asynchronous I/O which is based on signals (SIGIO to be precise) and there was a bug in GCC 5 (#66803) in which std::this_thread::sleep_for was interrupted by signals. It has been fixed in GCC 6.
The possible solutions are:
Upgrade your compiler to GCC 6+ or clang/LLVM.
Use a workaround like the one mentioned in the bug 66803 or try sleep_until:
auto wakeup_time = std::chrono::steady_clock::now() + std::chrono::seconds(1);
std::this_thread::sleep_until(wakeup_time);
Use blocking I/O (I believe you can simply open the serial device as a file and read from it).
Related
Is it possible to set timeout for std::cin?
For example, std::cin doesn't receive any data during 10 seconds - it throws an exception or returns an error.
Edited:
And what about timer from Boost library? As far as I know, it is portable library. Is it possible to ask timer of Boost library to throw exceptions after predefined period of time? I guess it can solve this problem.
It isn't possible to set a time out for std::cin in a portable way. Even when resorting to non-portable techniques, it isn't entirely trivial to do so: you will need to replace std::cin's stream buffer.
On a UNIX system I would replace the default stream buffer used by std::cin by a custom one which uses file descriptor 0 to read the input. To actually read the input I would use poll() to detect presence of input and set a timeout on this function. Depending on the result of poll() I would either read the available input or fail. To possibly cope with typed characters which aren't forwarded to the file descriptor, yet, it may be reasonable to also turn off the buffering done until a newline is entered.
When using multiple threads you can create a portable filtering stream buffer which uses on thread to read the actual data and another thread to use a timed condition variable waiting either for the first thread to signal that it received data or for the time out to expire. Note that you need to guard against spurious wake-ups to make sure that the timeout is indeed reached when there is no input. This would avoid having to tinker with the actual way data is read from std::cin although it still replaces the stream buffer used by std::cin to make the functionality accessible via this name.
I just figured out how to do that, polling the std::cin file descriptor.
poll function returns 0 if timeout occurs and no event happened, 1 if something happened, and -1 if error happened.
#include <iostream>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
bool stop = false;
void intHandler(int dummy)
{
stop = true;
}
std::string readStdIn()
{
struct pollfd pfd = { STDIN_FILENO, POLLIN, 0 };
std::string line;
int ret = 0;
while(ret == 0)
{
ret = poll(&pfd, 1, 1000); // timeout of 1000ms
if(ret == 1) // there is something to read
{
std::getline(std::cin, line);
}
else if(ret == -1)
{
std::cout << "Error: " << strerror(errno) << std::endl;
}
}
return line;
}
int main(int argc, char * argv[])
{
signal(SIGINT, intHandler);
signal(SIGKILL, intHandler);
while(!stop)
{
std::string line = readStdIn();
std::cout << "Read: " << line << std::endl;
}
std::cout << "gracefully shutdown" << std::endl;
}
There was a good answer posted here but the author removed it. It's a solution that worked well for me in the application I was developing. This is the essence of what the person wrote:
// compile: g++ -pthread thisfile.cpp
#include <iostream>
#include <thread>
int main() {
int x;
bool inputReceived = false;
time_t startTime = time(NULL);
time_t waitTime = 10;
std::cout << "Enter a number within " << waitTime << " seconds\n";
// spawn a concurrent thread that waits for input from std::cin
std::thread t1([&]() {
std::cin >> x;
inputReceived = true;
});
t1.detach();
// check the inputReceived flag once every 50ms for 10 seconds
while (time(NULL) < startTime + waitTime && !inputReceived) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
if (inputReceived) {
std::cout << "x = " << x << "\n";
return EXIT_SUCCESS;
}
std::cout << "timeout\n";
// TODO: find a way to kill the thread
return EXIT_FAILURE;
}
Be aware that the thread continues running after the timeout occurs, but it will terminate when the whole program terminates. If this is all you need then you don't need to worry about it.
However, there is no simple way to kill a detached thread. A solution would be to close the input stream, but that's not easy or desirable to do with std::cin. If you're lucky then you're going to use this with an easily closeable stream instead of std::cin. Closing the stream will cause input statement to fail and the the thread will probably just exit with an internal exception, but at least the thread will terminate.
I am trying to create a very threaded simple producer consumer toy implementation, but I'm running into a strange issue where the same consumer thread keeps getting rescheduled over and over again even though I am yielding control.
Here is an abridged version of my code. The Main method is simple , I start one producer and two consumer threads. I join to the producer thread and detach the two consumer threads. A getchar at the end of the main method keeps the program from exiting.
std::vector<int> UnprocessedValues;
std::vector<int> ProcessedValues;
std::mutex unprocessed_mutex;
void AddUnprocessedValue()
{
for (int i = 0; i <= 1000; ++i)
{
{
std::lock_guard<std::mutex> guard(unprocessed_mutex);
UnprocessedValues.push_back(i);
std::cout << "Thread id : " << std::this_thread::get_id() << " ";
printf("Unprocessed value added %i \n", UnprocessedValues.back());
}
}
}
void ProcessCurrentValue()
{
while (true)
{
unprocessed_mutex.lock();
if (UnprocessedValues.empty())
{
std::cout << "Thread id : " << std::this_thread::get_id() << " ";
printf("is waiting for values \n");
unprocessed_mutex.unlock();
std::this_thread::yield();
}
else
{
// Process value
unprocessed_mutex.unlock();
}
}
}
I expect that when there are no values present for consumers, they will both yield and end up giving the producer a chance to produce more.
In practice I see a single consumer getting stuck on waiting for values. Eventually the program rights itself, but something is obviously wrong.
If I was seeing the two consumers print that they are waiting in alternate, I would think that somehow the producer is getting shafted by the two consumers taking turns, but the actual result is that the same thread keeps getting rescheduled even though it just yielded.
Finally, when I change the if case from
if (UnprocessedValues.empty())
{
std::cout << "Thread id : " << std::this_thread::get_id() << " ";
printf("is waiting for values \n");
unprocessed_mutex.unlock();
std::this_thread::yield();
}
to
if (UnprocessedValues.empty())
{
unprocessed_mutex.unlock();
std::this_thread::yield();
std::cout << "Thread id : " << std::this_thread::get_id() << " ";
printf("is waiting for values \n");
}
I never see a busy wait. I realize that I could use a condition variable to fix this problem and I have already seen that using a small sleep instead of a yield works. I am just trying to understand why the yield would not work.
I'm new for threads and mutex and ı trying to learn them. I write some code that generally create a queue that enqueue all of the numbers from the file ( this file has nearly 20.000 lines and lots of information) since this file contains a lots of information for procees ı need to have multithreads, at the beginning user create the number of threads, then ı stuck at the part that in a while loop ı wanted see which threads enter the loop for dequing the id from queue, but apparently just the first created thread enters and dequeue all of them, ı used mutex for ensure that while a thread enters the loop make it process (dequeue a number) then unlock this mutex in order to other threads can enter but apprently ı did a mistake . Here is the code `
void printer( DynIntQueue & myQueue) // takes the Dynamic Queue
{
//int count = 0;
queMutex.lock(); // lock it before any threads come it
while(!myQueue.isEmpty()) // check this condition
{
int num;
cout << "Thread " << this_thread::get_id << " is working" << endl; // this is for printing out which threads enter this loop
myQueue.dequeue(num); // deqeueu this number from queue
queMutex.unlock(); // unlock this in order to next thread might enter
queMutex.lock(); // when this thread enters lock it in order to other threads to wait
}
queMutex.unlock(); // if myQueue is empty since it is firsly locked, unlock this
}`
My output is like this: Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working
This goes on until the myQueue is empty with the same thread. What can ı do ensure that other threads might enter this loop?
Edited: Here is the main part `
int main()
{
DynIntQueue firstQueue;
ifstream input;
string line;
int numofthreads;
input.open("data.tsv");
getline(input, line); // for first empty
int id, houseAge, avgRooms, avgBedRooms, latitue, longitute, medianPrice;
cout << "Please enter the number of threads you want " << endl;
cin >> numofthreads;
vector <thread> Threads(numofthreads);
while (!input.eof())
{
getline(input, line);
istringstream divider(line);
divider >> id >> houseAge >> avgRooms >> avgBedRooms >> latitue >> longitute >> medianPrice;
firstQueue.enqueue(id);
}
for (int i = 0; i < numofthreads; i++)
{
Threads[i] = thread(&printer, ref(firstQueue));
}
for (int i = 0; i < numofthreads; i++)
{
Threads[i].join();
}
return 0;
}
Note: std::this_thread::get_id() is a function, so you should be calling it. I assume this is just a copy/paste error.
If I add some work between opening and closing the queue, i clearly see two threads using the queue.
I don't think you have any issue with the code shown.
#include <iostream>
#include <thread>
#include <mutex>
#include <queue>
struct DynIntQueue {
bool isEmpty() const { return q_.empty(); }
void dequeue(int &elem) { elem = q_.front(); q_.pop(); }
std::queue<int> q_{{10, 20, 4, 8, 92}};
};
std::mutex queMutex;
void printer( DynIntQueue & myQueue) {
queMutex.lock();
while(!myQueue.isEmpty()) {
int num;
std::cout << "Thread " << std::this_thread::get_id() << " is working" << std::endl;
myQueue.dequeue(num);
queMutex.unlock();
std::cout << "working outside the lock" << std::endl;
std::cout << "working outside the lock" << std::endl;
std::cout << "working outside the lock" << std::endl;
std::cout << "working outside the lock" << std::endl;
std::cout << "working outside the lock" << std::endl;
queMutex.lock();
}
queMutex.unlock();
}
int main() {
std::cout << "Hello World!\n";
DynIntQueue q;
std::thread t1([&q]() { printer(q); });
std::thread t2([&q]() { printer(q); });
t1.join();
t2.join();
}
$ clang++-7 -pthread -std=c++17 -o main main.c
$ ./main
Hello World!
Thread 139686844172032 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock
Thread 139686835779328 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock
Thread 139686844172032 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock
Thread 139686835779328 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock
Thread 139686844172032 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock
I need to run an activity every so often while my program is running. In production code this is configurable with a default of 30 minutes, but in the example below I've used 5 seconds. Previously I had a std::thread that would loop once per second checking to see if it was time to run the activity OR if the program was closed. This allowed me to close the program at any time without having the .join() on the activity's thread block my application's exit waiting for its next iteration. At any moment it was less than a second away from checking to see if it should close or perform the activity.
I do not like the idea of wasting time checking every second for an activity that may only occur every 30 minutes while the program is running, so I attempted to switch it to a condition variable. I've included a small example of my implementation below. I want to be sure I'm using the right tools to do this. The issue I see with my code is unnecessary calls of the lambda expression which I'll explain below.
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
bool asking_thread_to_quit;
std::mutex cv_mutex;
std::condition_variable cv;
void RunThread()
{
{
std::lock_guard<std::mutex> lock(cv_mutex);
asking_thread_to_quit = false;
}
std::cout << "Started RunThread." << std::endl;
while(true)
{
{
std::unique_lock<std::mutex> lock(cv_mutex);
std::chrono::seconds delay(5);
if(cv.wait_for(lock, delay, [] { std::cout << "WAKEUP" << std::endl; return asking_thread_to_quit; })) // timed out
{
std::cout << "Breaking RunThread Loop." << std::endl;
break;
}
}
std::cout << "TIMER CODE!" << std::endl;
}
}
int main(int argc, char *argv[])
{
std::cout << "Program Started" << std::endl;
std::thread run_thread(RunThread);
// This is where the rest of the program would be implemented, but for the sake of this example, simply wait for user input to allow the thread to run in the background:
char test;
std::cin >> test;
{
std::lock_guard<std::mutex> lock(cv_mutex);
asking_thread_to_quit = true;
}
cv.notify_all();
std::cout << "Joining RunThread..." << std::endl;
run_thread.join();
std::cout << "RunThread Joined." << std::endl;
return 0;
}
If you execute the program and allow for one 5-second iteration to pass, it gives the following output:
Program Started
Started RunThread.
WAKEUP
WAKEUP
TIMER CODE!
WAKEUP
q <-- I typed this to quit.
Joining RunThread...
WAKEUP
Breaking RunThread Loop.
RunThread Joined.
You can see that it does the following:
(WAKEUP) Performs the check prior to waiting
Wait for five seconds
(WAKEUP) Performs the check
(TIMER CODE!) Executes the activity
(WAKEUP) Performs the check again before going back to waiting
Step 5 seems unnecessary as I just performed it a split second ago, but I believe it is necessary as .wait_for() doesn't know I'm using it inside of a while(true) loop. Is this something I'm stuck with, or is there a way to remove the initial check in the .wait_for() call? I'm guessing there is not as it would allow for the system to .wait_for() something that it doesn't need to wait for. This is what leads me to wonder if I'm using the right language features to begin with. Is there a better way?
The Answer
The answer given below goes into detail on other issues with my code as well as sparked an informative related conversation. I'm going to accept that answer as it helped me the most, but the quick answer to the question seems to be this:
asking_thread_to_quit could have been set to true during the TIMER CODE! section, requiring another check prior to waiting on the condition variable again.
Your code has a few issues with it.
void RunThread()
{
asking_thread_to_quit = false;
This is a race condition. You shouldn't modify a non-atomic shared variable in two different threads without synchronization.
std::cout << "Started RunThread." << std::endl;
while(true)
{
std::unique_lock<std::mutex> lock(cv_mutex);
std::chrono::seconds delay(5);
First using namespace std::literals::chrono_literals;. Then use 5s.
if(cv.wait_for(lock, delay, [] { std::cout << "WAKEUP" << std::endl; return asking_thread_to_quit; })) // timed out
{
std::cout << "Breaking RunThread Loop." << std::endl;
break;
}
else
{
std::cout << "TIMER CODE!" << std::endl;
}
the TIMER CODE usually shouldn't run within the std::mutex lock, as that means anyone sending a message is blocked until the timer code is finished.
}
}
Finally, WAKEUPs are spurious details. You could WAKEUP 50 times in that 5 seconds; condition variables do not guarantee a bounded number of checks.
asking_thread_to_quit = true;
cv.notify_all();
this again results in a race condition; your program does undefined behavior twice over now.
Changing asking_thread_to_quit to a std::atomic<bool> will get rid of the formal race condition and UB. It will, however, let your code miss a request to quit and mistakenly do another 5 second sleep followed by the task.
This is because the return value of your lambda could be calculated, then the asking_thread_to_quit=true and notify_all evaluates with nothing waiting on the condition variable (so nothing is woken up), then the condition variable is blocked on, 5 seconds pass, it wakes up returning false, then repeats the while loop.
With the mutex being held in all writes to the bool, the write cannot occur until after the lambda has returned and we are waiting on the condition with an unlocked mutex. This prevents the .notify_all() from being missed.
The cargo-cult solution to this is to always guard all reads and writes to asking_thread_to_quit by the cv_mutex. Then avoid holding the cv_mutex for any length of time, including while handling the timer wakeup.
std::unique_lock<std::mutex> lock_cv() {
return std::unique_lock<std::mutex>(cv_mutex);
}
void RunThread()
{
{
auto lock = lock_cv();
asking_thread_to_quit = false;
}
std::cout << "Started RunThread." << std::endl;
while(true)
{
{
auto lock = lock_cv();
using namespace std::literals::chrono_literals;
if(cv.wait_for(lock, 5s, [] { std::cout << "WAKEUP" << std::endl; return asking_thread_to_quit; })) // timed out
{
std::cout << "Breaking RunThread Loop." << std::endl;
break;
}
}
std::cout << "TIMER CODE!" << std::endl;
}
}
and in main:
{
auto lock = lock_cv();
asking_thread_to_quit = true;
}
cv.notify_all();
And yes, I intended for cv.notify_all() to be outside the mutex. It works; understanding why is outside the scope of the "cargo-cult" solution I'm providing here.
Finally, the WAKEUP is not spurious. The asking_thread_to_quit could have changed since the last time it was checked. Running the lambda guarantees we should fall asleep in a careful manner, with no gap between unlocking the mutex for waiting and waiting for notifications.
Spurious WAKEUPs can still occur; they would show up as more WAKEUPs than you expect.
I need a program to communicate with a subprocess that is relying on in- and
output. The problem is that I am apparently not able to use QProcess correctly.
The code further down should create a QProcess, start it and enter the main while loop. In there it prints all the output created by the subprocess to the console and subsequently asks the user for input which is then passed to the subprocess via write(...).
Originally I had two problems emerging from this scenario:
The printf's of the subprocess could not be read by the parent process.
scanf in the subprocess is not receiving the strings sent via write.
As for (1), I came to realize that this is a problem caused by the buffering of the subprocess' stdout. This problem can be solved easily with fflush(stdout) calls or manipulations regarding its flushing behavior.
The second problem is the one I can't wrap my head around. write gets called and even returns the correct number of sent bytes. The subprocess, however, is not continuing its excecution, because no new data is written to its output. The scanf seems not to be receiving the data sent. The output given by the program is:
Subprocess should have started.
124 bytes available!
Attempting to read:
Read: This is a simple demo application.
Read: It solely reads stdin and echoes its contents.
Read: Input exit to terminate.
Read: ---------
Awaiting user input: test
Written 5 bytes
No line to be read...
Awaiting user input:
I am seriously stuck right here. Google + heavy thinking having failed on me, I want to pass this on to you as my last beacon of hope. In case I am just failing to see the forest for all the trees, my apologies.
In case this information is necessary: I am working on 64bit MacOS X using Qt5 and the clang compiler. The subprocess-code is compiled with gcc on the same machine.
Thank you very much in advance,
NR
Main-Code:
int main() {
// Command to execute the subprocess
QString program = "./demo";
QProcess sub;
sub.start(program, QProcess::Unbuffered | QProcess::ReadWrite);
// Check, whether the subprocess is starting correctly.
if (!sub.waitForStarted()) {
std::cout << "Subprocess could not be started!" << std::endl;
sub.close();
return 99;
}
std::cout << "Subprocess should have started." << std::endl;
// Check, if the subprocess has written its starting message to the output.
if (!sub.waitForReadyRead()) {
std::cout << "No data available for reading. An error must have occurred." << std::endl;
sub.close();
return 99;
}
while (1) {
// Try to read the subprocess' output
if (!sub.canReadLine()) {
std::cout << "No line to be read..." << std::endl;
} else {
std::cout << sub.bytesAvailable() << " bytes available!" << std::endl;
std::cout << "Attempting to read..." << std::endl;
while (sub.canReadLine()) {
QByteArray output = sub.readLine();
std::cout << "Read: " << output.data();
}
}
std::cout << "Awaiting user input: ";
std::string input;
getline(std::cin, input);
if (input.compare("exit") == 0) break;
qint64 a = sub.write(input.c_str());
qint64 b = sub.write("\n");
sub.waitForBytesWritten();
std::cout << "Written " << a + b << " bytes" << std::endl;
}
std::cout << "Terminating..." << std::endl;
sub.close();
}
Subprocess-Code:
int main() {
printf("This is a simple demo application.\n");
printf("It reads stdin and echoes its contents.\n");
printf("Input \"exit\" to terminate.\n");
while (1) {
char str[256];
printf("Input: ");
fflush(stdout);
scanf("%s", str);
if (strcmp(str, "exit") == 0) return 0;
printf("> %s\n", str);
}
}
P.s: Since this is my first question on SO, please tell me if something is wrong concerning the asking style.
Solution
After many many more trials & errors, I managed to come up with a solution to the problem. Adding a call to waitForReadyRead() causes the main process to wait until new output is written by the subprocess. The working code is:
...
sub.waitForBytesWritten();
std::cout << "Written " << a + b << " bytes" << std::endl;
// Wait for new output
sub.waitForReadyRead();
...
I still don't have a clue why it works this way. I guess it somehow relates to the blocking of the main process by getline() vs blocking by waitForReadyRead(). To me it appears as if getline() blocks everything, including the subprocess, causing the scanf call never to be processed due to race conditions.
It would be great, if someone who understands could drop an explanation.
Thank you for your help :)
NR
This will not work. You are waiting for the sent bytes to be written but you are not waiting for the echo. Instead you are entering the getline() function waiting for new user input. Keep in mind that two processes are involved here where each process can be delayed to any degree.
Apart from this you should consider building your Qt application asynchronously (having an event loop) instead of trying the synchronous approach. This way your Qt application can do things in parallel... e.g. reading input or waiting for input from the remote process while still not being blocked and able to accept user input.