I have two threads in C++. One thread called alarm thread runs the function raiseAlarm() and the other thread called print thread runs the function called printMetrics. At a fixed interval, raiseAlarm sets an atomic variable to true. When the variable is true, printMetrics thread, which is spinning on the value of this atomic variable, prints some data. When I run this application, nothing happens. But if I put a cout anywhere in raiseAlarm, everything works fine. Why?
void Client::raiseAlarm()
{
bool no = false;
while(!stop.load(std::memory_order_acquire))
{
//cout << "about to sleep\n";
this_thread::sleep_for(std::chrono::seconds(captureInterval));
while(!alarm.compare_exchange_weak(no, true, std::memory_order_acq_rel))
{
no = false;
}
}
}
void Client::printMetrics()
{
bool yes = true;
while(!stop.load(std::memory_order_acquire))
{
while(!alarm.compare_exchange_weak(yes, false, std::memory_order_acq_rel) )
{
yes = true;
}
cout << "Msgs Rcvd: " << metrics.rcv_total.load(std::memory_order_acquire);
cout << "Msgs Sent: " << metrics.snd_total.load(std::memory_order_acquire);
cout << "Min latency: " << metrics.min_latency.load(std::memory_order_acquire);
cout << "Max latency: " << metrics.max_latency.load(std::memory_order_acquire);
metrics.reset();
}
}
Just a suggestion because I'm not so savvy with concurrency in C++, but make sure you don't forget to flush your output stream. Either stick a cout << flush; after all of your cout lines or add an << endl to each one (which will automatically flush your stream).
Related
I have what I think is a simple background worker thread setup that has been working for millions of executions over many days. Recently I got a hang at this point in my code and am wondering if I've missed something in my setup that led to a deadlock.
Code snippet (will not compile):
cout << "Starting." << endl;
atomic<bool> keepThreadRunning;
mutex coutMutex;
keepThreadRunning = true;
auto doBackgroundTask1 = [&keepThreadRunning, &backgroundData1, &coutMutex] () {
size_t numSteps = 0;
while (keepThreadRunning && backgroundData1->doOneTask()) {
++numSteps;
}
coutMutex.lock();
cout << " Did " << numSteps << " background 1 tasks." << endl;
coutMutex.unlock();
};
auto doBackgroundTask2 = [&keepThreadRunning, &backgroundData2, &coutMutex] () {
size_t numSteps = 0;
while (keepThreadRunning && backgroundData2->doOneTask()) {
++numSteps;
}
coutMutex.lock();
cout << " Did " << numSteps << " background 2 tasks." << endl;
coutMutex.unlock();
};
thread backgroundThread1(doBackgroundTask1);
thread backgroundThread2(doBackgroundTask2);
doForegroundWork();
keepThreadRunning = false;
backgroundThread1.join();
backgroundThread2.join();
cout << "Finished." << endl;
I suspect I'm doing something wrong with the atomic or the mutex. I have no way of proving this to you, but the two sets of background data and the foreground work are completely isolated, so the threads have no buried locks or conflicts over that data. I'm showing two threads just in case I've missed something with the mutex around cout.
i am trying to generate a class for reading from a specific serial device.
For the start process it is necessary to send a char '1', then i have to wait for a response (254 and 255).
Within a period of 10 milliseconds i must sent the next command to the device, but this time the command length is 5 char.
When the communication hasn´t been send in the correct time, the device will run into a timeout and is sending me 255,255,255,2,4.
So i need different sizes of reading and the most importing thing for me is a timeout for the communication, cause otherwise the system will stop working by missing some values.
Therefore i have tried to generate a class using boost::asio::async_read.
It is working in the correct way, i can define the timeout,also the size of bytes to be read. When the device isn´t sending the correct size, the routine is going to be left.
But only the first time, when i try it a second time, the device isn´t sending me something. I have tried to use .open again, but it isn´t solving the issue. Also deactivating the close-function isn´t solving the issue, then the routine is running into an error.
Can someone give me a small tip for my issue. Maybe i am to blind to see my problem.... Bernd
ConnectionWithTimeout::ConnectionWithTimeout(int timeout_)
: timer_(io_service_, boost::posix_time::milliseconds(timeout_))
, serial_port_(io_service_) {
}
void ConnectionWithTimeout::ReadNumberOfChars(int numberOfCharactersToRead_)
{
buffer_.resize(numberOfCharactersToRead_);
for (int i = 0; i < numberOfCharactersToRead_; ++i) {
std::cout << "Clear Buffer[" << i << "]" << std::endl;
buffer_[i] = 0;
}
timer_.async_wait(boost::bind(&::ConnectionWithTimeout::Stop, this));
//async read from serial port
boost::asio::async_read(serial_port_, boost::asio::buffer(buffer_),
boost::bind(&ConnectionWithTimeout::ReadHandle, this,
boost::asio::placeholders::error));
io_service_.run();
}
void ConnectionWithTimeout::Stop() {
std::cout << "Connection is being closed." << std::endl;
serial_port_.close();
std::cout << "Connection has been closed." << std::endl;
}
void ConnectionWithTimeout::ReadHandle(const boost::system::error_code& ec) {
if (ec) {
std::cout << "The amount of data is to low: " << ec << std::endl;
for (std::vector<char>::iterator it = buffer_.begin();
it != buffer_.end(); ++it)
{
std::cout << int(*it) << std::endl;
}
}
else {
std::cout << "The amount of data is correct: " << ec << std::endl;
for (std::vector<char>::iterator it = buffer_.begin(); it !=
buffer_.end(); ++it)
{
std::cout << int(*it) << std::endl;
}
}
}
I am seeing unusual signal numbers (for example 50, 80 or 117) from the following code when waiting for a child process to terminate. I am only seeing this from one particular child process, and I have no access to the process source code and it only happens some of the time.
I want to know what these unusual values mean, given NSIG == 32, and where I can find some documentation in the headers or man pages?
Note that this code runs in a loop sending progressively more menacing signals until the child terminates.
int status, signal;
if (waitpid(m_procId, &status, WNOHANG) < 0) {
LOGERR << "Failed to wait for process " << name() << ": " <<
strerror(errno) << " (" << errno << ")";
break;
} else if (WIFEXITED(status)) {
m_exitCode = WEXITSTATUS(status);
terminated = true;
LOGINF << "Process " << name() << " terminated with exit code " << m_exitCode;
} else if (WIFSIGNALED(status)) {
signal = WTERMSIG(status); // !!! signal is sometimes 50, 80 or 117 !!!
terminated = true;
LOGINF << "Process " << name() << " terminated by signal " << signal;
} else {
LOGWRN << "Process " << name() << " changed state but did not terminate. status=0x" <<
hex << status;
}
This is running under OSX 10.8.4, but I have also seen it in 10.9 GM seed.
EDIT Modifying the code as below makes the code more robust, however sometimes the child process gets orphaned as I guess the loop doesn't do enough to kill the child process.
else if (WIFSIGNALED(status)) {
signal = WTERMSIG(status);
if (signal < NSIG) {
terminated = true;
LOGINF << "Process " << name() << " terminated by signal " << signal;
} else {
LOGWRN << "Process " << name() << " produced unusual signal " << signal
<< "; assuming it's not terminated";
}
}
Note this code is part of the Process::unload() method of this class.
From the OS X manpage for waitpid, when specifing WNOHANG, you should check for a return of 0:
When the WNOHANG option is specified and no processes wish to report status, wait4() returns a process
id of 0.
The waitpid() call is identical to wait4() with an rusage value of zero. The older wait3() call is the
same as wait4() with a pid value of -1.
The code posted does not check for this, which suggests to me that the value of status is likely junk (the value of the int is never initialized). This could cause what you are seeing.
EDIT: status is indeed only set when waitpid returns > 0.
I wrote the following code:
#include<iostream>
#include<pthread.h>
using namespace std;
void* func(void *i)
{
cout<<"in func "<<endl;
}
int main()
{
pthread_t threads[5];
for(int i=0;i<5;i++)
{
pthread_create(&threads[i], NULL, func, (void*)i);
cout<<"next for loop"<<endl;
}
pthread_exit(NULL);
return 0;
}
The output was:
From the output it seems that the endl line changing property after first display of 'next for loop' gets delayed and endl of 'next for loop' and 'in func' are executed one after the other. This happened everytime i ran the program. Can you tell me the reason for this delay?
I think that
cout <<"next for loop" << endl;
is a compact way of writing
cout << "next for loop";
cout << endl;
Since you are working in a multi-threaded environment, the order of execution is unpredictable. That's what happened in your particular case:
cout << "next for loop";
cout << "in func ";
cout << endl;
cout << endl;
...
Streams have locks to protect them, so they single-thread. You'll need some sort of buffer of your own to collect results while running threads.
There is not much to say about the behavior of multi-threaded code where there is no explicit control of the execution flow with locks and semaphores.
For example, in the code you have posted the following can happen:
just after pthread_create() the next for loop sentence gets printed
the newly created thread starts and prints its sentence entirely (in func and endl)
The main thread is run again and it prints the remaining endl
It may also happen that the two endl overleaps in a different way (first the one of the main thread, then the one of the newly created thread).
Note: using std::endl and \n or \r\n is not the same thing.
std::endl also includes an output buffer flushing operation.
As pointed to by some answers above cout << something << endl are two separate pieces of instructions and in a multi-threaded environment cout << endl can very well we pre-empted by another thread just after it has done cout << something. Try this C style newline character(escape sequence) :
#include<iostream>
#include<pthread.h>
using namespace std;
void* func(void *i)
{
cout<<"in func \n";
//cout << "\n";
//cout<<endl;
}
int main()
{
pthread_t threads[5];
for(int i=0;i<5;i++)
{
pthread_create(&threads[i], NULL, func, (void*)i);
cout<<"next for loop\n";
//cout << "\n";
//cout<<endl;
}
pthread_exit(NULL);
return 0;
}
I'm modifying the stock quoter example from the wustl CORBA release. The assignment is to implement a reply handler for the StockFactory class that handles calls to get_stock()
Here's my FactoryHandler implementation:
FactoryHandler_i.h:
#ifndef TAO_TUTORIALS_QUOTER_AMI_CLIENT_FACTORYHANDLER_I_H
#define TAO_TUTORIALS_QUOTER_AMI_CLIENT_FACTORYHANDLER_I_H
#include "QuoterS.h"
class Stock_Factory_Handler_i : public POA_Quoter::AMI_Stock_FactoryHandler
{
public:
Stock_Factory_Handler_i (int *response_count, ::Quoter::Stock_var& result);
void get_stock (::Quoter::Stock_ptr ami_return_val);
void get_stock_excep (::Messaging::ExceptionHolder * excep_holder);
private:
int *response_count_;
::Quoter::Stock_var& result_;
};
#endif /* TAO_TUTORIALS_QUOTER_AMI_CLIENT_HANDLER_I_H */
FactoryHandler_i.cpp:
#include "FactoryHandler_i.h"
#include "ace/streams.h"
Stock_Factory_Handler_i::
Stock_Factory_Handler_i (int *response_count, ::Quoter::Stock_var& result)
: response_count_ (response_count), result_ (result)
{
}
void
Stock_Factory_Handler_i::get_stock (::Quoter::Stock_ptr ami_return_val)
{
cout << "storing result" << endl;
result_ = ami_return_val;
(*this->response_count_)++;
}
void
Stock_Factory_Handler_i::get_stock_excep (::Messaging::ExceptionHolder * excep_holder)
{
// We ignore the exception, but this counts as a response, otherwise
// the application would not finish.
cerr << "Exception raised while getting stock"
<< endl;
(*this->response_count_)++;
}
And the client.cpp, from just before the part where changes have been made:
// ...
// Create and activate the handler...
int response_count = 0;
Single_Query_Stock_Handler_i handler_i (&response_count);
Quoter::AMI_Single_Query_StockHandler_var handler =
handler_i._this ();
// Create and activate the factory handler...
Quoter::Stock_var result;
Stock_Factory_Handler_i factory_handler_i (&response_count, result);
Quoter::AMI_Stock_FactoryHandler_var factory_handler =
factory_handler_i._this();
// Send all the requests, careful with error handling
int request_count = 0;
for (int i = 2; i != argc+1; ++i) {
try {
// Get the stock object
cout << "looking up stock symbol " << argv[i] << endl;
factory->sendc_get_stock (factory_handler.in (), argv[i]);
sleep(3); // wait for a response
cout << "converting result" << endl;
Quoter::Single_Query_Stock_var stock =
Quoter::Single_Query_Stock::_narrow (result.in ());
cout << "checking result" << endl;
CORBA::Any any;
any <<= stock;
CORBA::TypeCode_var tc = any.type();
cout << tc->kind() << endl;
if (CORBA::is_nil (stock.in ())) {
cerr << "Cannot get single query interface for <"
<< argv[i] << ">" << endl;
continue;
}
cout << "reading result" << endl;
stock->sendc_get_price_and_names (handler.in ());
request_count++;
}
catch (Quoter::Invalid_Stock_Symbol &) {
cerr << "Invalid stock symbol <"
<< argv[i] << ">" << endl;
}
}
while (response_count < 2 * request_count // multiply by 2 because both handlers increment response_count
&& orb->work_pending ()) {
orb->perform_work ();
}
// ...
When running the client, the output is:
looking up stock symbol MSFT
converting result
checking result
14
Cannot get single query interface for <MSFT>
(The 14 is the typecode for Stock, that's only for debugging)
Notably missing from the above is the "storing result" message that's supposed to be printed in the FactoryHandler's get_stock() callback method. I'm at a loss as to why, since the sendc_get_stock() method doesn't produce any (immediate) errors and is basically just a copy of the StockHandler's code, and from there it's the responsibility of the AMI/ORB interface to make the callback. But the original example (with a StockHandler only) works fine.
What am I doing wrong (and how do I fix it)?
EDIT: another bit of information: on the server side, StockFactory's get_stock() method does get called.
Sorry, I've no aswer for you. But a hint, ask your question at TOA's maling list at http://www.cs.wustl.edu/~schmidt/ACE-mail.html
HTH
I think that your problem is that work_pending returns true only if the ORB has immediate work to do, so it returns false in the time after your client sent his request and before the server sends his reply.
To validate that, simply remove the && orb->work_pending() condition from the loop, and use the version of perform_work that takes a timeout argument.