Imp Concepts in C++ and Threading

You might also like

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 12

two threads, running in different processes, are effectively isolated from each

other
http://www.qnx.com/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.neutrino
_getting_started%2Fexamples.html
the fork() function, duplicates the current process but not everything.
int main (int argc, char **argv)
{
int retval;
printf ("This is most definitely the parent process\n");
fflush (stdout);
retval = fork ();
printf ("Which process printed this?\n");
return (EXIT_SUCCESS);
}
After the fork() call, both processes are going to execute the second printf() c
all! If
you run this program, it prints something like this:
This is most definitely the parent process
Which process printed this?
Which process printed this?
Both processes print the second line.
The only way to tell the two processes apart is the fork() return value in retva
l. In the
newly created child process, retval is zero; in the parent process, retval is th
e child s
process ID.
Clear as mud? Here s another code snippet to clarify:
printf ("The parent is pid %d\n", getpid ());
fflush (stdout);
if (child_pid = fork ()) {
printf ("This is the parent, child pid is %d\n",
child_pid);
} else {
printf ("This is the child, pid is %d\n",
getpid ());
}
The exec() family transforms the current process into another one. What I mean b
y
that is that when a process issues an exec() function call, that process ceases
to run the
current program and begins to run another program. The process ID doesn t change
that process changed into another program.
The spawn() family, on the other hand, doesn t do that. Calling a member of the
spawn() family creates another process (with a new process ID) that corresponds
to
the program specified in the function s arguments.
/* To run ls and keep going: */
spawnl (P_WAIT, "/bin/ls", "/bin/ls", "-t", "-r", "-l", NULL);
/* To transform into ls: */
execl ("/bin/ls", "/bin/ls", "-t", "-r", "-l", NULL);

P_WAIT The calling process (your program) is blocked until the newly
created program has run to completion and exited.
P_NOWAIT The calling program doesn t block while the newly created program
runs. This allows you to start a program in the background, and
continue running while the other program does its thing.

To create a joinable thread (meaning that another thread can synchronize to its
termination via pthread_join()), you d use:
(default)
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE);
To create one that can t be joined (called a detached thread), you d use:
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
pthread_join() and
pthread_barrier_wait().

with the pthread_join(), the worker threads are done and dead in
order for the main thread to synchronize with them. But with the barrier, the th
reads
are alive and well. In fact, they ve just unblocked from the pthread_barrier_wait(
)
when all have completed.
+++++++++++++++++++++++++++++
Mutexes can be applied only to threads in a single process and do not work betwe
en processes as do semaphores.
Difference between binary semaphore and mutex:+++++++++++++++++++++++++++++++++++++++++++++++
Virtual destructors are needed because at destruction time, you don't always kno
w what type you're dealing with:
Base *make_me_an_object()
{
if (the_moon_is_full())
return new Derived();
else
return new Base();
}
int main()
{
Base *p = make_me_an_object();
delete p;
}
The delete in the above program's main doesn't know whether its p points to a Ba
se or a Derived object, but if the Base destructor is virtual (as it should be),
then delete can use *p's vtable to find the right destructor.
By contrast, at construction time, you always know what kind of object you're cr
eating. (And in case you don't, then you can create a factory or "virtual constr
uctor" that does know.)

+++++
constructor http://www.cplusplus.com/doc/tutorial/classes/
Here we have declared a constructor that takes two parameters of type int. There
fore the following object declaration would be correct:
CExample ex (2,3);
But,
CExample ex;
Would not be correct, since we have declared the class to have an explicit const
ructor, thus replacing the default constructor.
But the compiler not only creates a default constructor for you if you do not sp
ecify your own. It provides three special member functions in total that are imp
licitly declared if you do not declare your own. These are the copy constructor,
the copy assignment operator, and the default destructor.

Notice how we appended =0 to virtual int area () instead of specifying an implem


entation for the function. This type of function is called a pure virtual functi
on, and all classes that contain at least one pure virtual function are abstract
base classes.
The main difference between an abstract base class and a regular polymorphic cla
ss is that because in abstract base classes at least one of its members lacks im
plementation we cannot create instances (objects) of it.
But a class that cannot instantiate objects is not totally useless. We can creat
e pointers to it and take advantage of all its polymorphic abilities. Therefore
a declaration like:
CPolygon poly;
would not be valid for the abstract base class we have just declared, because tr
ies to instantiate an object. Nevertheless, the following pointers:
1
2
CPolygon * ppoly1;
CPolygon * ppoly2;
would be perfectly valid.

++++++++++++++++++++++
pthread_t mm_createthread(void* (*start_routine)(void* ), void* pArg)
{

pthread_t hThread = -1;


pthread_attr_t attr;
// Initialize a thread-attribute object
pthread_attr_init (&attr);
//Set thread detach state attribute
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
// Create a thread
pthread_create (&hThread, &attr, start_routine, pArg);
return hThread;
}

Detached Threads
What should I do when my thread doesn t return anything useful, and I don t have to
wait for its completion? Do I have to call pthread_join() anyway just for cleanup purpose?
Fortunately, not. Pthreads offers a mechanism to tell the system: I am starting
this thread, but I am not interested about joining it. Please perform any cleanup action for me, once the thread has terminated. This operation is called detac
hing a thread. We can detach a thread as follows:
During thread creation using the detachstate thread attribute.
From any thread, using pthread_detach().
++++++++++++++++++++++++++++++++++
Remember: delete p does two things: it calls the destructor
and it deallocates the memory.
Round Robin
The RR scheduling algorithm is identical to FIFO, except that the thread will no
t run forever if there's another thread at the same priority. It runs only for a
system-defined timeslice whose value you can determine by using the function sc
hed_rr_get_interval(). The timeslice is usually 4 ms, but it's actually 4 times
the ticksize, which you can query or set with ClockPeriod().
What happens is that the kernel starts an RR thread, and notes the time. If the
RR thread is running for a while, the time allotted to it will be up (the timesl
ice will have expired). The kernel looks to see if there is another thread at th
e same priority that's ready. If there is, the kernel runs it. If not, then the
kernel will continue running the RR thread (i.e., the kernel grants the thread a
nother timeslice).
Comparisons Process creation and threads
Now, let's compare the three methods using various categories, and we'll also de
scribe some of the trade-offs.
With system 1, we see the loosest coupling. This has the advantage that each of
the three processes can be easily (i.e., via the command line, as opposed to rec
ompile/redesign) replaced with a different module. This follows naturally, becau
se the "unit of modularity" is the entire module itself. System 1 is also the on

ly one that can be distributed among multiple nodes in a Neutrino network. Since
the communications pathway is abstracted over some connectioned protocol, it's
easy to see that the three processes can be executing on any machine in the netw
ork. This may be a very powerful scalability factor for your design -- you may n
eed your system to scale up to having hundreds of machines distributed geographi
cally (or in other ways, e.g., for peripheral hardware capability) and communica
ting with each other.
Once we commit to a shared memory region, however, we lose the ability to distri
bute over a network. Neutrino doesn't support network-distributed shared memory
objects. So in system 2, we've effectively limited ourselves to running all thre
e processes on the same box. We haven't lost the ability to easily remove or cha
nge a component, because we still have separate processes that can be controlled
from the command line. But we have added the constraint that all the removable
components need to conform to the shared-memory model.
In system 3, we've lost all the above abilities. We definitely can't run differe
nt threads from one process on multiple nodes (we can run them on different proc
essors in an SMP system, though). And we've lost our configurability aspects -now we need to have an explicit mechanism to define which "input," "processing,"
or "output" algorithm we want to use (which we can solve with shared objects, a
lso known as DLLs.)
So why would I design my system to have multiple threads like system 3? Why not
go for the maximally flexible system 1?
Well, even though system 3 is the most inflexible, it is most likely going to be
the fastest. There are no thread-to-thread context switches for threads in diff
erent processes, I don't have to set up memory sharing explicitly, and I don't h
ave to use abstracted synchronization methods like pipes, POSIX message queues,
or message passing to deliver the data or control information -- I can use basic
kernel-level thread-synchronization primitives. Another advantage is that when
the system described by the one process (with the three threads) starts, I know
that everything I need has been loaded off the storage medium (i.e., I'm not goi
ng to find out later that "Oops, the processing driver is missing from the disk!
"). Finally, system 3 is also most likely going to be the smallest, because we w
on't have three individual copies of "process" information (e.g., file descripto
rs).
To sum up: know what the trade-offs are, and use what works for your design.
The disadvantage of threads is the classic problem faced by engineers used to RT
OS s and that is the fact that a bug in one thread can corrupt the memory being us
ed by another thread. When a thread crashes it is natural to start debugging tha
t thread but it may well be that the bug is in code utilised only by another thr
ead. These issues can be very difficult to track down! - See more at: http://www
.electronicsweekly.com/open-source-engineering/linux/multi-thread-or-multi-proce
ss-2009-03/#sthash.oL7tW5ze.dpuf
So the correct balance has to be struck between security and performance and thi
s will require some analysis of the application and the performance capabilities
of the hardware. ++++++++++++++++++++++++++++++
The copy constructor receives an object of its own class as an argument, and all
ows to create a new object which is copy of another without building it from scr
atch.
User-defined copy constructor
#include <iostream>

class Array {
public:
int size;
int* data;
implicit Array(int size)
: size(size), data(new int[size])
{
}
~Array()
{
delete[] this->data;
}
};
int main() -->http://en.wikipedia.org/wiki/Copy_constructor
{
Array first(20);
first.data[0] = 25;
{
}

Array copy = first;


std::cout << first.data[0] << " " << copy.data[0] << std::endl;
// (1)

first.data[0] = 10;

// (2)

}
Output
25 25
Segmentation fault
The problem with this constructor is that it performs a shallow copy of the data
pointer. It only copies the address of the original data member; this means
they both share a pointer to the same chunk of memory, which is not what we wan
t. When the program reaches line (1), copy's destructor gets called
(because objects on the stack are destroyed automatically when their scope ends
). Array's destructor deletes the data array of the original, therefore when it
deleted copy's data,
because they share the same pointer, it also deleted first's data. Line (2) now
accesses invalid data and writes to it! This produces the infamous segmentation
fault.
If we write our own copy constructor that performs a deep copy then this problem
goes away.
--------------------------1. Call C functions from C++
In this section we will discuss on how to call C functions from C++ code.
Here is the C code (Cfile.c):
#include <stdio.h>
void f(void)
{

printf("\n This is a C code\n");


}
The first step is to create a library of this C code. The following steps create
a shared library :
$ gcc -c -Wall -Werror -fPIC Cfile.c
$ gcc -shared -o libCfile.so Cfile.o
The shared library libCfile.so is produced as a result of above two commands.
Here is the main C++ code (main.cpp) :
#include <iostream>
extern "C" {
void f();
}
void func(void)
{
std::cout<<"\n being used within C++ code\n";
}
int main(void)
{
f();
func();
return 0;
}
The C function f() is declared within the notation extern
er that it has C type linkage.

to tell the cpp compil

Now, compile the code (make sure that the shared library libCfile.so is linked t
o the code):
$ g++ -L/home/himanshu/practice/ -Wall main.cpp -o main -lCfile
Before running the executable make sure that the path of shared library is conta
in in the environment variable LD_LIBRARY_PATH.
$ export LD_LIBRARY_PATH=/home/himanshu/practice:$LD_LIBRARY_PATH
Now run the executable main :
$ ./main
This is a C code
being used within C++ code
.....................................
Private Constructor is useful when you want to control the object creation of a
class. Lets try in code
#include <iostream>
using namespace std;
class aTestClass
{
aTestClass()//////////private constructor of this class
{
cout<<"Object created\n";
}
public:

};
int main()
{
aTestClass a;
aTestClass *anObject;
}
The line aTestClass a causes an error because this line is indirectly trying to
access the private constructor.comment out this line and run the program .it run
s absolutely fine.Now question is how to create object in such case.
/*
Creational Pattern: SINGLETON
Author: Rajesh V.S
Language: C++
Email: rajeshvs@msn.com
*/
#include <iostream>
using namespace std;
class Singleton
{
private:
static bool instanceFlag;
static Singleton *single;
Singleton()
{
//private constructor
}
public:
static Singleton* getInstance();
void method();
~Singleton()
{
instanceFlag = false;
}
};
bool Singleton::instanceFlag = false;
Singleton* Singleton::single = NULL;
Singleton* Singleton::getInstance()
{
if(! instanceFlag)
{
single = new Singleton();
instanceFlag = true;
return single;
}
else
{
return single;
}
}
void Singleton::method()
{
cout << "Method of the singleton class" << endl;
}

int main()
{
Singleton *sc1,*sc2;
sc1 = Singleton::getInstance();
sc1->method();
sc2 = Singleton::getInstance();
sc2->method();
return 0;
}
Nothrow constant
This constant value is used as an argument for operator new and operator new[] t
o indicate that these functions shall not throw an exception on failure, but ret
urn a null pointer instead.
By default, when the new operator is used to attempt to allocate memory and the
handling function is unable to do so, a bad_alloc exception is thrown. But when
nothrow is used as
argument for new, it returns a null pointer instead.
ptr = new (std::nothrow) int[1024];
if(ptr == NULL)
assert();
---------------------------------------static_cast is also able to perform all conversions allowed implicitly (not only
those with pointers to classes), and is also able to perform the opposite of th
ese. It can:
Convert from void* to any pointer type. In this case, it guarantees that if the
void* value was obtained by converting from that same pointer type, the resultin
g pointer value is the same.
Convert integers, floating-point values and enum types to enum types.</i>

For example, suppose you allocated the object via a typical new
expression:
Fred* p = new Fred();
Then the destructor Fred::~Fred() will automagically get called when you delete
it via:
delete p; // Automagically calls p->~Fred()
You should not explicitly call the destructor, since doing so won't release the
memory that was
allocated for the Fred object itself. Remember: delete p does two things: it cal
ls the destructor
and it deallocates the memory.
Hi,
When you use std:: before cout you are telling the compiler that you want to use
the name cout that is in the namespace called standard. There are lots of ways
you can do it.
http://www.dreamincode.net/forums/topic/18071-difference-between-cout-and-stdcou
t/
1)
01

#include <iostream>
02
03
int main()
04
{
05
using std::cout;
06

using std::endl;

07
cout << "Hello, world" << endl;
08
09
return 0;
10
}
2)
01
#include <iostream>
02
03
using namespace std;
04
05
int main()
06
{
07
08
cout << "Hello, world" << endl;
09
10
return 0;
11
}
3)
1
#include <iostream>
2
3
int main()
4
{
5
std::cout << "Hello, world" << std::endl;
6
7

return 0;
8
}

++++++++++++
// Using free( ):
int *pResources( malloc( 2 * sizeof( int ) ) );
free( pResources );
pResources = NULL;
pResources = ( malloc( sizeof( int ) ) );
free( pResources ); // No different from the previous call.
pResources = NULL;
// Using delete/delete[ ]:
int *pResources( new int[ 2 ] );
delete [ ] pResources;
pResources = NULL;
pResources = ( new int( 0 ) );
delete pResources; // Different from the previous call.
pResources = NULL;
As you can see in the code example above, free( ) can delete an array of resourc
es, or a single resource.
With delete/delete[ ], you have to tell it what type of block it's deleting. Fo
r example, if use delete[ ],
you're deleting an array. If you use delete, you're deleting a single object.
+++++++++++++++++++
Vtables contain pointers to virtual functions
Whenever a class itself contains virtual functions or overrides virtual function
s from a parent class the compiler builds a vtable for that class. This means th
at not all classes have a vtable created for them by the compiler.
Tiger t1;
/* below, an Animal object pointer is set to point
to an object of the derived Tiger class */
Animal *a1 = &t1;
a1 -> getWeight();
/*
The call above gets translated to this,
assuming the pointer to the vtable for the
Tiger class is called vptr1
:
*(a1 -> vptr1 -> getWeight())
*/
+++++++++++++++++++++++++++++++++++
https://www.youtube.com/watch?v=RF7DF4kfs1E
https://www.youtube.com/watch?v=KqGZvSLWcbs
https://www.youtube.com/watch?v=CR569T-B2M0

info functions
info scope addnumbers
info files

You might also like