Shuva's blog
C++ : A lock with a timeout : Example code 
Thursday, April 9, 2009, 11:18 AM - Programming
When we use a mutex and wait on it, we basically ASSUME that somebody else is going to release the lock. Most of the time this assumption works. But there can be a situation when you dont want to wait forever on the lock. In such cases we want to have a GetLock() function that has a time out.

One such lock exists in Boost and they are:
boost::timed_mutex and
boost::recursive_timed_mutex

Unfortunately there are too many good resources that explain boost locks with examples. Here is one crude example that I had to write for my own practice.


#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/locks.hpp>
#include <sys/types.h>
#include <linux/unistd.h>

_syscall0(pid_t,gettid)

boost::timed_mutex m_mutex;

void Thread1_CreateObjectAndWait() {
//Get the lock
boost::timed_mutex::scoped_lock guard(m_mutex);
std::cout << gettid() << ": Thread got the lock" << std::endl;

boost::system_time timeout = boost::get_system_time() +
boost::posix_time::milliseconds(10000);

std::cout << gettid()
<< ": Waiting for thread 2 to unlock or else timeout"
<< std::endl;
bool ret = m_mutex.timed_lock(timeout);

if (ret == true) {
std::cout << gettid() << ": Got the lock before timeout"
<< std::endl;
} else {
std::cout << gettid() << ": Got the lock after timeout"
<< std::endl;
}

}

void Thread2_Unlock() {
std::cout << gettid() << " : Unlocking the mutex " << std::endl;
m_mutex.unlock() ;
}


int main() {

//Create thread 1, which will lock itself and wait for thread 2
//to unlock or timeout.
boost::thread thread1(&Thread1_CreateObjectAndWait);

//sleep some time to give time for thread 1 to start.
sleep(2);

//create thread 2 which will unlock before thread 1 gets a timeout.
boost::thread thread2(&Thread2_Unlock);

//Create thread 3, which will lock itself and wait for thread 2
//to unlock or timeout.
boost::thread thread3(&Thread1_CreateObjectAndWait);

thread1.join();
thread2.join();
thread3.join();
return 0;
}


The above code compiled with g++ with the following command:

g++ example.cpp -I<path to boost include dir>  <path to boost lib dir>/libboost_thread-gcc34-mt.a  -lpthread


The o/p should look something like:
28061: Thread  got the lock
28061: Waiting for thread 2 to unlock or else timeout
28062 : Unlocking the mutex
28061: Got the lock before timeout
28063: Thread got the lock
28063: Waiting for thread 2 to unlock or else timeout
28063: Got the lock after timeout



PS: To compile on Windows, replace gettid() with GetCurrentThreadId() and remove the linux specific header file.

Happy Boosting.//

add comment ( 1043 views )   |  0 trackbacks   |  permalink   |   ( 3 / 84 )
Little known, undocumented VC++ "macro" called __LPREFIX 
Saturday, August 23, 2008, 01:34 PM - Programming
__LPREFIX is actually not a pre-processor macro though it is used like a macro. It is the MS VC++ compiler and not the pre-processpor which actually handles this. This can be used to add the L-prefix to a string thereby making it a wide string (wchar_t).

Example: The following two lines are the same.
wchar_t* msg = L"Hello World!";
wchar_t* msg = __LPREFIX("Hello World!");

This however does not explain the need to use this prefix. Where would it be useful?

If you have something like
#define MSG "Hello World!"

You cant do
wchar_t* msg = L MSG;  //error

The only way to get around this is either to call the Narrow to Wide conversion routines or just say
wchar_t* msg = __LPREFIX( MSG );

If you are using only wchar_t in your code and you want the wide version of macros like __DATE__, __LINE__, __FUNCTION__, etc then this could be helpful.
#define __WDATE__ __LPREFIX( __DATE__ )
#define __WTIME__ __LPREFIX( __TIME__ )
#define __WFUNCTION__ __LPREFIX( __FUNCTION__ )

As a side note, a cross platform (and the correct) way to get the wide version of a predefined macro like __FILE__ is :

#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)

Another undocumented VC++ related string "macro" is __SPREFIX which is used to create a managed string object(.Net) from a string.
Example:
System::String^ date = __SPREFIX( __DATE__ )

Fun: The MS VC++ 2005, VC++ 2008 compiler crashes if you try to compile the following program:
#include <windows.h>
#define DATA __SPREFIX( __DATE__ )
int main() {
DATA;
return 0;
}

Well, they never documented it anyways.

Related link: Go get Microsoft Visual Studio 2008 Express Edition. Its free.

Happy Prefixing.//
add comment ( 93 views )   |  0 trackbacks   |  permalink   |   ( 3 / 45 )
The "I am here" debugging technique. 
Tuesday, August 5, 2008, 05:48 AM - Programming
No matter how good is your debug logging or your debugger, there are times when you think that its quicker to just put in one printf("I am here"); statement to debug your code. One thing to remember is not forgetting to print the the End-Of-Line character.

printf("I am here"); is different from printf("I am here\n");
In the former case, the print may get delayed and if your program crashes immediately you may be even get this line printed making you think that the control did not reach this line. So always use printf("I am here\n"); if you at all use this debugging technique.

Happy Debugging.//
1 comment ( 73 views )   |  0 trackbacks   |  permalink   |   ( 2.9 / 37 )
Declaring variables in C++ : Style or efficiency 
Wednesday, June 25, 2008, 11:54 AM - Programming
Did you know that C++ allows you to declare variables anywhere in the code and not necessarily at the beginning of the function? Of course you do! If you dont you are at the wrong place in the internet. Get away from my blog --- Shoooooooo!

Most C++ programmers who come from C background, however many times prefer to declare variables in the beginning of the function. They say its their style. They say it makes code look better. They don't want to have variable declarations scattered all around. If you are among them, think again. This feature was not introduced for mere flexibility of a programmer's style.

Your program is likely to perform better if you delay the declaration of your variable as late as possible.


An object/variable in a function may be unused because of a possible early exit, an if-then-else condition or because of an exception. Declaring late avoids unnecessary constructions of objects which may not be used in the function.

Moreover by declaring all objects, destructors of the unused objects are called unnecessary.

Additional tip:
If you face a compiler error is declaring an object inside a "case" of a switch statement use an extra "{" "}" pair as shown below:

    switch(action) {
case WRITE:
Writer writer;
int x;
writer.Write("Some stuff");
break;
case READ:
Reader reader;
reader.Read(data);
break;
default:
break;
}


You may get an error saying "initialization of 'writer' is skipped by 'case' label" if you have defined a constructor for Writer or Reader class. The fix is below:

    switch(action) {
case WRITE:
{
Writer writer;
int x;
writer.Write("Some stuff");
}
break;
case READ:
{
Reader reader;
reader.Read(data);
}
break;
default:
break;
}

Happy Programming.//

add comment ( 117 views )   |  0 trackbacks   |  permalink   |   ( 3.1 / 34 )
Best C++ coding standard I have ever read 
Monday, May 26, 2008, 11:55 AM - Programming
Powered By ReadTheWords.com
A good C++ coding standard is one which tell you when you may break the rule. For that you need to un-satisfy the justification of the recommendation. In other words, one quality of a good coding standard is one which gives a justification for every item.

Secondly, it should contain language specific suggestions and guidelines (stuff which are legal, but best avoided outside your college/school).

C++ Coding Standard by Todd Hoff is the best I have ever read. Where was it all the time?

Happing coding.//
add comment ( 154 views )   |  0 trackbacks   |  permalink   |   ( 2.9 / 39 )

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Next> Last>>