Threading in C++ to keep two functions running parallely - c++

I have a code congaing two functions func1 and func2. Role of both the function is same. Keep reading a directory continuously and write the names of file present in their respective log files. Both functions are referring a common log function to write the logs. I want to use introduce threading in my code such that both of them keep on running parallely but both should not access the log function at same time. How to achieve that?

This is a classic case of needing a mutex.
void WriteToLog(const char *msg)
{
acquire(mutex);
logfile << msg << endl;
release(mutex);
}
The above code won't "copy and paste" into your system, since mutexes are system specific - pthread_mutex would be the choice if you are using pthreads. C++11 has it's own mutex and thread functionality, and Windows has another variant.

From Sajal's comments:
tried pthread_create(&thread1, NULL, start_opca, &opca); pthread_join( thread1, NULL); pthread_create(&thread2, NULL, start_ggca, &ggca); pthread_join( thread2, NULL);
But the problem with this is that it will wait for one thread to finish before starting next. I don't want that.
the join function blocks the calling thread, until the thread you call join for, finishes. In your case, calling join on the first thread before creating the second, guarantees that the first thread will end before the second one begins.
You should create the two threads first, then join them both (instead of interspersing the creations and join of both).
Additionally, the access to the log should be extracted into common code for both (a logging function, a logging class etc. Within the extracted code, the log access should be guarded using a mutex.
If you have an implementation (partially) supporting c++11, you should use std::thread and std::mutex for this. Otherwise, you should use boost::thread. If you have access to neither, use pthreads under linux.

On linux, you will need to use pthreads

Since both threads are reading/writing from/to I/O (reading dirs and writing log files) there's no need for multi-threading: you gain no speed improvement parallelizing the task since every I/O access is enqueued at lower levels.

This C language Code may give you some hint. To answer your question:
You should use mutex in pthread to make sure that the log file could only be access by one thread at the same time.
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t LogLock = PTHREAD_MUTEX_INITIALIZER;
char* LogFileName= "test.log";
void* func_tid0( void* a) {
int i;
for(i=0; i < 50; i++ ) {
pthread_mutex_lock(&LogLock);
fprintf((FILE*)a, "write to log by thread0:%d\n", i);
pthread_mutex_unlock(&LogLock);
}
}
void* func_tid1(void* a) {
int i;
for(i=0; i < 50; i++ ) {
pthread_mutex_lock(&LogLock);
fprintf((FILE*)a, "write to log by thread1:%d\n", i);
pthread_mutex_unlock(&LogLock);
}
}
int main() {
pthread_t tid0, tid1;
FILE* fp=fopen(LogFileName, "wb+");
pthread_create(&tid0, NULL, func_tid0, (void*) fp );
pthread_create(&tid1, NULL, func_tid1, (void*) fp );
void* ret;
pthread_join(tid0, &ret);
pthread_join(tid1, &ret);
}

Your another question isn't exist.
Because the main thread is suspend at your first pthread_join, but it's not mean the second thread doesn't run. Actually the second thread is beginning at pthread_create(thread1).
And actually pthread_mutex casuses your program serial.

Related

Thread-safe CreateThread?

Is the PrintHello() function pthreads example thread-safe? I find these kind of examples online but I don't understand how they can be thread-safe. On the other hand, if I add a mutex around the code in PrintHello() function then the example would not be multithreaded as all threads would queue in wait for the previous thread to exit the PrintHello() function. Also, moving it to a class would not help as the member would have to be statically declared as pointers to non-static functions is not allowed with CreateThread() it seems. Any way of solving this?
#include <WinBase.h>
#include <stdio.h>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#define NUM_THREADS 500
DWORD PrintHello(LPVOID oHdlRequest)
{
long tid;
tid = (long)GetCurrentThreadId();
/* randomly sleep between 1 and 10 seconds */
int sleepTime = rand() % 10 + 1;
sleep(sleepTime);
printf("Hello World! It's me, thread #%ld!\n", tid);
return 0;
}
int main (int argc, char *argv[])
{
/* initialize random seed: */
srand (time(NULL));
HANDLE threads[NUM_THREADS];
long t;
DWORD nThreadID;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
threads[t] = CreateThread(
// Default security
NULL,
// Default stack size
0,
// Function to execute
(LPTHREAD_START_ROUTINE)&PrintHello,
// Thread argument
NULL,
// Start the new thread immediately
0,
// Thread Id
&nThreadID
);
if (!threads[t]){
printf("ERROR; return code from CreateThread() is %d\n", GetLastError());
exit(-1);
}
}
}
Since you're including WinBase.h, I'll assume that you're using MSVC. MSVC CRT has long supported multithreaded access - in fact, current versions of MSVC no longer support a single threaded CRT that isn't threadsafe. I believe that VS 2003 is the last version of MSVC that supported the single threaded CRT.
In the multithreaded CRT, functions are threadsafe and if they access global data internally they will synchronize among themselves. So each printf() executed in ProcessRequest() will be atomic with respect to other printf() calls in other threads (actually, the locks are based on streams, so the printf() calls will be atomic with respect to other CRT functions that use stdout).
The exceptions to this are if you use I/O functions that are explicitly documented to not take locks (so you can synchronize on them yourself for performance reasons), or if you define _CRT_DISABLE_PERFCRIT_LOCKS in which case the CRT assumes that all I/O will be performed on a single thread.
See http://msdn.microsoft.com/en-us/library/ms235505.aspx
POSIX makes similar guarantees that printf() will be threadsafe:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/flockfile.html
All functions that reference (FILE *) objects, except those with names ending in _unlocked, shall behave as if they use flockfile() and funlockfile() internally to obtain ownership of these (FILE *) objects.
http://newsgroups.derkeiler.com/Archive/Comp/comp.programming.threads/2009-06/msg00058.html (A post by David Butenhof):
POSIX/UNIX requires that printf() itself be atomic; it's not legal that two parallel calls to printf() from separate threads can mix their data. But those two writes may appear on the output in either order.
The code is not thread-safe in general; printf is not normally
reentrant. (An implementation could add reentrace to it as
an additional feature, but I don't know of any which do.) You
must add some sort of protection around it. (Under Windows,
a so called CriticalSection should be sufficient.)
You'll also have to find a thread safe alternative to sleep;
I can't find any documentation which says that it is reentrant
(and the Posix variant isn't), but Microsoft doesn't seem to
document reentrance in general. A classical solution for this
would be to create a Mutex, block it, and then call
WaitForSingleObject on it with the desired timeout;
CreateWaitableTimer and WaitForSingleObject should work as
well. (As I said, Microsoft's documentation is very deficient;
but WaitForSingleObject must be safe, since it is des igned to
be used when waiting for a mutex, among other things.)
Note too that unless you join the created threads, you'll
probably run off the end of main, and the process will
terminate before any of the threads will have run. (Under
Windows, you can use WaitForSingleObject or
WaitForMultipleObjects to join.)
An even better solution would be to the standard threads, if you
have a compiler which supports them, or Boost threds, if you
don't.

Multithreading using pthread in C++ with shared variables

I'm new to threading (and C/C++ for that matter), and I'm attempting to use multiple threads to access shared variables.
In the main, I've created a variable char inputarray[100];
Thread 1: This thread will be reading data from stdin in 2 byte bursts, and appending them to the inputarray. (input by feeding a file in)
Thread 2: This thread will be reading data 1 byte at a time, performing a calculation, and putting its data into an output array.
Thread 3: This thread will be outputting data from the output array in 2 byte bursts. (stdout)
I've attempted the input part and got it working by passing a struct, but would like to do it without using a struct, but it has been giving me problems.
If I can get input down, I'm sure I'll be able to use a similar strategy to complete output. Any help would be greatly appreciated.
Below is a rough template for the input thread.
#include <stdio.h>
#include <pthread.h>
using namespace std;
void* input(void* arg) {
char reading[3];
fread(reading,1,2,stdin);
//append to char inputarray[]..???
}
int main() {
char inputarray[100];
pthread_t t1;
pthread_create(&t1, NULL, &input, &inputarray);
void *result;
pthread_join(t1,&result);
return 0;
}
Several issues:
I think array on stack is very bad choice for shared variable, because it has a fixed size and it's not clear from Thread 2 and 3 where to put new elements or where to read elements from. I would propose to use std::vector or std::deque instead.
Initially your container is empty. Then Thread 2 pushes some elements to it.
Thread 3 is polling (or waiting on condition variable) container, and once it found new elements - print them
You have to synchronize access to shared variable with mutex (consider pthread mutex, std::mutex or boost::mutex). You might also want to use condition variable to notify Thread 3 about new elements in the queue. But for initial implementation it's not needed.
Do you really have to use pthread primitives? Normally it's much easier and safer (i.e. exception safety) to use std::thread, std::mutex (if you have modern compiler), or boost::thread, boost::mutex otherwise.
You are on the correct track:
As a note the pthreads libraries are C libs so you need to declare the callbacks as C functions:
extern "C" void* input(void* arg);
Personally I would pass the address of the first element:
pthread_create(&t1, NULL, &input, &inputarray[0]);
This then makes your code look like this:
void* input(void* arg) {
try
{
char* inputarray = (char*)arg;
size_t inputLocation = 0;
// Need to make sure you don't over run the buffer etc...
while(!finished())
{
fread(&inputarray[inputLocation],1,2,stdin);
inputLocation += 2;
}
}
catch(...){} // Must not let exceptions escape a thread.
return NULL;
}
The trouble with this style is that you are putting the responsibility for coordination into each individual thread. The writer thread has to check for end the reader thread has to check there is data available etc. All this needs coordination so now you need some shared mutexes and condition variables.
A better choice is to move that responsibility into the object the does the communication. So I would create a class that has the basic operations needed for communication then make its methods do the appropriate checks.
class Buffer
{
public:
void write(......); //
void read(.....); //
private:
// All the synchronization and make sure the two threads
// behave nicely inside the object.
};
int main()
{
pthread_t threads[3];
std::pair<Buffer, Buffer> comms;
// comms.first inputToRead
// comms.second processesToOutput
pthread_create(&threads[0], NULL, &readInput, &comms.first); // Input
pthread_create(&threads[1], NULL, &procInput, &comms); // Processing
pthread_create(&threads[2], NULL, &genOutput, &comms.second); // Output
void *result;
pthread_join(threads[0],&result);
pthread_join(threads[1],&result);
pthread_join(threads[2],&result);
}
As a side note:
Unless there is something very strange about your processing of data. This would probably be faster written as a single threaded application.

PThread Question

I am trying to make a small thread example. I want to have a variable and each thread try to increment it and then stop once it gets to a certain point. Whenever the variable is locked, I want some sort of message to be printed out like "thread x trying to lock, but cannot" so that I KNOW it's working correctly. This is my first day coding threads so feel free to point out anything unnecessary in the code here -
#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define NUM_THREADS 2
pthread_t threads[NUM_THREADS];
pthread_mutex_t mutexsum;
int NUMBER = 0;
void* increaseByHundred(void* threadid) {
if(pthread_mutex_lock(&mutexsum))
cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT";
else {
for(int i=0;i<100;i++) {
NUMBER++;
cout<<"\nNUMBER: "<<NUMBER;
}
pthread_mutex_unlock(&mutexsum);
pthread_exit((void*)0);
}
}
int main(int argc, char** argv) {
int rc;
int rc1;
void* status;
pthread_attr_t attr;
pthread_mutex_init(&mutexsum, NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
rc = pthread_create(&threads[0], &attr, increaseByHundred, (void*)0);
rc1 = pthread_create(&threads[1], &attr, increaseByHundred, (void*)1);
pthread_attr_destroy(&attr);
while(NUMBER < 400)
pthread_join(threads[0], &status);
pthread_mutex_destroy(&mutexsum);
pthread_exit(NULL);
}
I was following a tutorial found here https://computing.llnl.gov/tutorials...reatingThreads
and tried to adapt their mutex example to this idea. The code increments it up to 199 and then stops. I'm guessing because the threads are only doing their routine once. Is there a way make them just do their routine other than when you create them so I could say
while something
do your routine
?
I have the pthread_join there just because it was similar to what that tutorial had on theirs. I don't really even get it that clearly though. I'm pretty sure that line is the problem...I just don't know how to fix it. Any help is appreciated.
Whenever the variable is locked, I want some sort of message to be printed out like "thread x trying to lock, but cannot" so that I KNOW it's working correctly.
Why do you want that? You are just learning about threads. Learn the basics first. Don't go diving off the deep end into pthread_mutex_trylock or mutexes configured for error checking. You need to learn to walk before you can learn how to run.
The basics involves a mutex initialized use with default settings and using pthread_mutex_lock to grab the lock. With the default settings, pthread_mutex_lock will only return non-zero if there are big, big problems. There are only two problems that can occur here: Deadlock, and a bad mutex pointer. There is no recovery from either; the only real solution is to fix the code. About the only thing you can do here is to throw an exception that you don't catch, call exit() or abort(), etc.
That some other thread has locked the mutex is not a big problem. It is not a problem at all. pthread_mutex_lock will block (e.g., go to sleep) until the lock becomes available. A zero return from pthread_mutex_lock means that the calling thread now has the lock. Just make sure you release the lock when you are done working with the protected memory.
Edit
Here's a suggestion that will let you see that the threading mechanism is working as advertised.
Upon entry to increaseByHundred print a time-stamped message indicating entry to the function. You probably want to use C printf here rather than C++ I/O. printf() and related functions are thread-safe. C++ 2003 I/O is not.
After a successful return from pthread_mutex_lock print another time-stamped message indicating that a successful lock.
sleep() for a few seconds and then print yet another time-stamped message prior to calling pthread_mutex_unlock().
Do the same before calling pthread_exit().
One last comment: You are checking for an error return from pthread_mutex_lock. For completeness, and because every good programmer is paranoid as all get out, you should also check the return status from pthread_mutex_unlock.
What about pthread_exit? It doesn't have a return status. You could print some message after calling pthread_exit, but you will only reach that statement if you are using a non-compliant version of the threads library. The function pthread_exit() cannot return to the calling function. Period. Worrying about what happens when pthreads_exit() returns is a tinfoil hat exercise. While good programmers should be paranoid beyond all get out, they should not be paranoid schizophrenic.
pthread_mutex_lock will normally just block until it acquire the lock, and that's why the line cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT"; is not ran.
You also have problems in
while(NUMBER < 400)
pthread_join(threads[0], &status);
because you just have 2 threads and number will never reach 400. You also want to join thread[0] on first iteration, then thread[1]...
pthread_mutex_trylock():
if (pthread_mutex_trylock(&mutex) == EBUSY) {
cout << "OMG NO WAY ITS LOCKED" << endl;
}
It is also worth noting that if the mutex is not locked, it will be able to acquire the lock and then it will behave like a regular pthread_mutex_lock().

Simple C++ Threading

I am trying to create a thread in C++ (Win32) to run a simple method. I'm new to C++ threading, but very familiar with threading in C#. Here is some pseudo-code of what I am trying to do:
static void MyMethod(int data)
{
RunStuff(data);
}
void RunStuff(int data)
{
//long running operation here
}
I want to to call RunStuff from MyMethod without it blocking. What would be the simplest way of running RunStuff on a separate thread?
Edit: I should also mention that I want to keep dependencies to a minimum. (No MFC... etc)
#include <boost/thread.hpp>
static boost::thread runStuffThread;
static void MyMethod(int data)
{
runStuffThread = boost::thread(boost::bind(RunStuff, data));
}
// elsewhere...
runStuffThread.join(); //blocks
C++11 available with more recent compilers such as Visual Studio 2013 has threads as part of the language along with quite a few other nice bits and pieces such as lambdas.
The include file threads provides the thread class which is a set of templates. The thread functionality is in the std:: namespace. Some thread synchronization functions use std::this_thread as a namespace (see Why the std::this_thread namespace? for a bit of explanation).
The following console application example using Visual Studio 2013 demonstrates some of the thread functionality of C++11 including the use of a lambda (see What is a lambda expression in C++11?). Notice that the functions used for thread sleep, such as std::this_thread::sleep_for(), uses duration from std::chrono.
// threading.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
int funThread(const char *pName, const int nTimes, std::mutex *myMutex)
{
// loop the specified number of times each time waiting a second.
// we are using this mutex, which is shared by the threads to
// synchronize and allow only one thread at a time to to output.
for (int i = 0; i < nTimes; i++) {
myMutex->lock();
std::cout << "thread " << pName << " i = " << i << std::endl;
// delay this thread that is running for a second.
// the this_thread construct allows us access to several different
// functions such as sleep_for() and yield(). we do the sleep
// before doing the unlock() to demo how the lock/unlock works.
std::this_thread::sleep_for(std::chrono::seconds(1));
myMutex->unlock();
std::this_thread::yield();
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
// create a mutex which we are going to use to synchronize output
// between the two threads.
std::mutex myMutex;
// create and start two threads each with a different name and a
// different number of iterations. we provide the mutex we are using
// to synchronize the two threads.
std::thread myThread1(funThread, "one", 5, &myMutex);
std::thread myThread2(funThread, "two", 15, &myMutex);
// wait for our two threads to finish.
myThread1.join();
myThread2.join();
auto fun = [](int x) {for (int i = 0; i < x; i++) { std::cout << "lambda thread " << i << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); } };
// create a thread from the lambda above requesting three iterations.
std::thread xThread(fun, 3);
xThread.join();
return 0;
}
CreateThread (Win32) and AfxBeginThread (MFC) are two ways to do it.
Either way, your MyMethod signature would need to change a bit.
Edit: as noted in the comments and by other respondents, CreateThread can be bad.
_beginthread and _beginthreadex are the C runtime library functions, and according to the docs are equivalent to System::Threading::Thread::Start
Consider using the Win32 thread pool instead of spinning up new threads for work items. Spinning up new threads is wasteful - each thread gets 1 MB of reserved address space for its stack by default, runs the system's thread startup code, causes notifications to be delivered to nearly every DLL in your process, and creates another kernel object. Thread pools enable you to reuse threads for background tasks quickly and efficiently, and will grow or shrink based on how many tasks you submit. In general, consider spinning up dedicated threads for never-ending background tasks and use the threadpool for everything else.
Before Vista, you can use QueueUserWorkItem. On Vista, the new thread pool API's are more reliable and offer a few more advanced options. Each will cause your background code to start running on some thread pool thread.
// Vista
VOID CALLBACK MyWorkerFunction(PTP_CALLBACK_INSTANCE instance, PVOID context);
// Returns true on success.
TrySubmitThreadpoolCallback(MyWorkerFunction, context, NULL);
// Pre-Vista
DWORD WINAPI MyWorkerFunction(PVOID context);
// Returns true on success
QueueUserWorkItem(MyWorkerFunction, context, WT_EXECUTEDEFAULT);
Simple threading in C++ is a contradiction in terms!
Check out boost threads for the closest thing to a simple approach available today.
For a minimal answer (which will not actually provide you with all the things you need for synchronization, but answers your question literally) see:
http://msdn.microsoft.com/en-us/library/kdzttdcb(VS.80).aspx
Also static means something different in C++.
Is this safe:
unsigned __stdcall myThread(void *ArgList) {
//Do stuff here
}
_beginthread(myThread, 0, &data);
Do I need to do anything to release the memory (like CloseHandle) after this call?
Another alternative is pthreads - they work on both windows and linux!
CreateThread (Win32) and AfxBeginThread (MFC) are two ways to do it.
Be careful to use _beginthread if you need to use the C run-time library (CRT) though.
For win32 only and without additional libraries you can use
CreateThread function
http://msdn.microsoft.com/en-us/library/ms682453(VS.85).aspx
If you really don't want to use third party libs (I would recommend boost::thread as explained in the other anwsers), you need to use the Win32API:
static void MyMethod(int data)
{
int data = 3;
HANDLE hThread = ::CreateThread(NULL,
0,
&RunStuff,
reinterpret_cast<LPVOID>(data),
0,
NULL);
// you can do whatever you want here
::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);
}
static DWORD WINAPI RunStuff(LPVOID param)
{
int data = reinterpret_cast<int>(param);
//long running operation here
return 0;
}
There exists many open-source cross-platform C++ threading libraries you could use:
Among them are:
Qt
Intel
TBB Boost thread
The way you describe it, I think either Intel TBB or Boost thread will be fine.
Intel TBB example:
class RunStuff
{
public:
// TBB mandates that you supply () operator
void operator ()()
{
// long running operation here
}
};
// Here's sample code to instantiate it
#include <tbb/tbb_thread.h>
tbb::tbb_thread my_thread(RunStuff);
Boost thread example:
http://www.ddj.com/cpp/211600441
Qt example:
http://doc.trolltech.com/4.4/threads-waitconditions-waitconditions-cpp.html
(I dont think this suits your needs, but just included here for completeness; you have to inherit QThread, implement void run(), and call QThread::start()):
If you only program on Windows and dont care about crossplatform, perhaps you could use Windows thread directly:
http://www.codersource.net/win32_multithreading.html

Use of threads in C++

Can you tell me how can I use threads in C++ programs, and how can I compile it as it will be multithreaded? Can you tell me some good site where I can start from root?
Thanks
I haven't used it myself, but I'm told that the Boost thread libraries make it incredibly easy.
http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html
For Unix/Linux/BSD, there's pthread library: tutorial.
I guess there are equivalent in Win32 API.
Process and Threads
Synchronization
I use tbb_thread class from intel threading building blocks library.
There are many threads libraries wich are compatible with c++. So at first you must select one. I prefer OpenMP or POSIX threads (also known as pthreads). How to compile it depends on library you have choose.
I use a library my university prof wrote. It is very simple to implement and works really well (used it for quite some time now). I will ask his permission to share it with you.
Sorry for the wait ahead, but gotta check :)
++++++EDIT+++++++
Ok, so I talked to my prof and he doesn't mind if I share it here. Below are the .h and .cpp files for the 'RT Library' written by Paul Davies
http://www.filefactory.com/file/7efbeb/n/rt_h
http://www.filefactory.com/file/40d9a6/n/rt_cpp
Some points to be made about threads and the use of this library:
0) This tutorial will explain thread creation and use on a windows platform.
1) Threads in c++ are usually coded as part of the same source (unlike processes where each process has its own source file and function main() )
2) When a process is up and running, it can create other threads by making appropriate Kernel calls.
3) Multiple threads run faster than multiple processes since they are a part of the same process which results in less of an overhead for the OS, and reduced memory requirements.
4) What you will be using in your case is the CThread class in the rt library.
5) (Make sure rt.h and rt.cpp are a part of your 'solution' and make sure to include rt.h in your main.cpp)
6) Below is a part of code from your future main thread (in main.cpp, of course) where you will create the thread using the CThread class.
void main()
{
CThread t1(ChildThread1, ACTIVE, NULL) ;
. . .
t1.WaitForThread() ; // if thread already dead, then proceed, otherwise wait
}
The arguments of t1 in order are: Name of the function acting as our thread, the thread status (it can be either ACTIVE or SUSPENDED - depending on what you want), and last, a pointer to an optional data you may want to pass to the thread at creation. After you execute some code, you'll want to call the WaitForThread() function.
7) Below is a part of code from your future main thread (in main.cpp, of course) where you will describe what the child thread does.
UINT _ _stdcall ChildThread1(void *args)
{
. . .
}
The odd looking thing there is Microsoft's thread signature. I'm sure with a bit of research you can figure out how to do this in other OSs. The argument is the optional data that could be passed to the child at creation.
8) You can find the detailed descriptions of the member functions in the rt.cpp file. Here are the summaries:
CThread() - The constructor responsible for creating the thread
Suspend() - Suspends a child thread effectively pausing it.
Resume() - Wakes up a suspended child thread
SetPriority(int value) - Changes the priority of a child thread to the value
specified
Post(int message) - Posts a message to a child thread
TerminateThread() - Terminates or Kills a child thread
WaitForThread() - Pauses the parent thread until a child thread terminates.
If the child thread has already terminated, parent will not pause
9) Below is an example of a sample complete program. A clever thing you can do is create multiple instantiations of a single thread.
#include “..\wherever\it\is\rt.h” //notice the windows notation
int ThreadNum[8] = {0,1,2,3,4,5,6,7} ; // an array of thread numbers
UINT _ _stdcall ChildThread (void *args) // A thread function
{
MyThreadNumber = *(int *)(args);
for ( int i = 0; i < 100; i ++)
printf( "I am the Child thread: My thread number is [%d] \n", MyThreadNumber) ;
return 0 ;
}
int main()
{
CThread *Threads[8] ;
// Create 8 instances of the above thread code and let each thread know which number it is.
for ( int i = 0; i < 8; i ++) {
printf ("Parent Thread: Creating Child Thread %d in Active State\n", i) ;
Threads[i] = new CThread (ChildThread, ACTIVE, &ThreadNum[i]) ;
}
// wait for threads to terminate, then delete thread objects we created above
for( i = 0; i < 8; i ++) {
Threads[i]->WaitForThread() ;
delete Threads[i] ; // delete the object created by ‘new’
}
return 0 ;
}
10) That's it! The rt library includes a bunch of classes that enables you to work with processes and threads and other concurrent programming techniques. Discover the rest ;)
You may want to read my earlier posting on SO.
(In hindsight, that posting is a little one-sided towards pthreads. But I'm a Unix/Linux kind of guy. And that approach seemed best with respect to the original topic.)
Usage of threads in C/C++:
#include <iostream>
using namespace std;
extern "C"
{
#include <stdlib.h>
#include <pthread.h>
void *print_message_function( void *ptr );
}
int main()
{
pthread_t thread1, thread2;
char *message1 = "Thread 1";
char *message2 = "Thread 2";
int iret1, iret2;
iret1 = pthread_create( &thread1, NULL, print_message_function (void*) message1);
iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
//printf("Thread 1 returns: %d\n",iret1);
//printf("Thread 2 returns: %d\n",iret2);
cout<<"Thread 1 returns: %d\n"<<iret1;
cout<<"Thread 2 returns: %d\n"<<iret2;
exit(0);
}
void *print_message_function( void *ptr )
{
char *message;
message = (char *) ptr;
//printf("%s \n", message);
cout<<"%s"<<message;
}