Solved

Need example to do thread pool in C++ pthread

Posted on 2008-06-12
25
8,724 Views
Last Modified: 2009-12-16
Hi expert,

Does anyone has example how to write a thread pool application in C++ pthread?

For example, a single input file get processed by x number of threads...each thread will process y amount of record, and end all threads until the all records in the input file is processed.

An example will really help.

Thanks
0
Comment
Question by:4eyesgirl
  • 12
  • 10
  • 3
25 Comments
 
LVL 40

Expert Comment

by:evilrix
ID: 21772017
C++ has no concept of threads... this is support provided by the OS so it is very platform specific. You can use Boost threads, which will help abstract this.
http://www.boost.org/doc/libs/1_35_0/doc/html/thread.html

Otherwise, we'll need to know the platform you are targeting before we can give you specific help.

BTW: Windows supports CThreadPool, which is an abstract representation of a thread pool.
http://msdn.microsoft.com/en-us/library/9tz6fz1e(VS.80).aspx
http://msdn.microsoft.com/en-us/library/39f8fee2(VS.80).aspx
0
 
LVL 86

Expert Comment

by:jkr
ID: 21772055
Take a look at http://www.codeproject.com/KB/threads/threads.aspx ("A Thread Pool compatible with Win32 and pthreads API") - the article comes with full sample code.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21772090
0
 
LVL 86

Expert Comment

by:jkr
ID: 21772094
And a little more compact example http://mia.ece.uic.edu/~papers/WWW/multi-thread/thread-pool-server.c and even a ready-made library for that: http://www.garypennington.net/libwp/docs/html/ ("libwp - A Worker Pool Library")
0
 

Author Comment

by:4eyesgirl
ID: 21772158
Let me take a look of the above link and I will let get back to you...most likely tomorrow.

Thanks
0
 

Author Comment

by:4eyesgirl
ID: 21772213
I need example for all platforms...portable..
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21772389
>> I need example for all platforms...portable..

Below is an example of creating a thread pool using Boost.

You can download precompiled Boost for Windows here: http://www.boost-consulting.com/products/free
#include <iostream>

#include <string>

#include <csignal>

#include <cstdlib>

#include <boost/thread.hpp>

 

// Thread functor

class thread_func

{

public:

	thread_func(std::sig_atomic_t & sigQuit): m_sigQuit(sigQuit){}

 

	void operator()()

	{

		m_sigQuit = 0; // Reset signal

 

		{

			boost::mutex::scoped_lock lock(sm_mutex);

			std::cout << "Running thread" << std::endl;

		}

 

		// Start transaction here

 

		while(!m_sigQuit)

		{

			// Process your queue here (don't forget to protect it with a mutex)

			boost::thread::yield();

		}

 

		// Commit transaction here

 

		{

			boost::mutex::scoped_lock lock(sm_mutex);

			std::cout << "Ending thread" << std::endl;

		}

 

		m_sigQuit = 0; // Reset signal

	}

 

private:

	// Used to signal thread to quit -- must be a reference!!!

	std::sig_atomic_t & m_sigQuit;
 

	static boost::mutex sm_mutex;

};
 

boost::mutex thread_func::sm_mutex;

 

int main()

{

	std::sig_atomic_t sigQuit = 0;

	thread_func tfunc(sigQuit);

 

	std::cout << "Starting threads" << std::endl;
 

	// Created a thread pool

	boost::thread_group tg;

	for(int n = 0 ; n < 10 ; ++n)

	{

		tg.create_thread(tfunc);

	}

 

	system("pause");

 

	std::cout << "Terminating threads" << std::endl;

	

	sigQuit = 1; // Signal thread to stop
 

	tg.join_all(); // Wait for threads to re-join

 

	std::cout << "Terminating process" << std::endl;

 

	system("pause");
 

	return 0;

}

Open in new window

0
 

Author Comment

by:4eyesgirl
ID: 21782470
JKR -

The compact example you provided at http://mia.ece.uic.edu/~papers/WWW/multi-thread/thread-pool-server.c  is very similar what I need.

There is one thing...the handle_requests_loop() is a loop forever.

I actually want to add a flag at the end in the main() to tell all the thread need to exit instead of loop forever.  Any idea what is the easiest way to accomplish this task?

Right now the handle_requests_loop() contains a while(1) loop.

I want to use pthread_join to join all the thread but there is one problem, the thread won't die.

I need a way to signal all the thread to die when I need them to...But I need to keep the while(1) loop to keep track on the requests, so I am not sure how to accomplish this task.

Any suggestion will be apprecaited.
0
 

Author Comment

by:4eyesgirl
ID: 21782482
For all,

I actually prefer example in pthread, sorry if I wasn't clear at the begining.

0
 
LVL 86

Expert Comment

by:jkr
ID: 21782499
>>I need a way to signal all the thread to die when I need them to.

What about using 'pthread_cancel()'?
0
 

Author Comment

by:4eyesgirl
ID: 21782587
Can pthread_cancel() used with pthread_join?
0
 
LVL 86

Expert Comment

by:jkr
ID: 21782658
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

Author Comment

by:4eyesgirl
ID: 21782699
I read that article also but it didn't say if you can use it with pthread_join also.

DO you happen to know for sure it is okay?
0
 

Author Comment

by:4eyesgirl
ID: 21782726
Okay,

I did a simple test,and I don't think pthread_join can be used with pthread_cancel.

When the pthread_join() invoke, the application is blocked until all thread exit.

So where should I call the pthread_cancel at?
0
 
LVL 86

Expert Comment

by:jkr
ID: 21782774
If 'pthread_calcel()' does not work, you could use 'pthread_kill()' to send a signal to the thread to terminate itself after your 'while' loop exits.
0
 

Author Comment

by:4eyesgirl
ID: 21782866
JKR -

If you look at the handle_requests_loop() function....

It start with a while(1) ....loop forever...

and if there is number of requests, it handle the requests,
if there is no requests, it uses the pthread_cond_wait() to block the code and wait for the singal invoke.

So the thread will stuck in two places...
1. the pthread_cond_wait()
2. the whiel(1) loop

Here is my problem, lets said after all the requests is performed...I want to mark the last request as the last one, and once I handle the last request, I want all the threads to be terminated...

and I don't know how to get this done...Can you let me know where you will add the "pthread_cancel" at?  And where will you add the pthread_kill() function call at?  

void*

handle_requests_loop(void* data)

{

    int rc;	                    /* return code of pthreads functions.  */

    struct request* a_request;      /* pointer to a request.               */

    int thread_id = *((int*)data);  /* thread identifying number           */
 

#ifdef DEBUG

    printf("Starting thread '%d'\n", thread_id);

    fflush(stdout);

#endif /* DEBUG */
 

    /* lock the mutex, to access the requests list exclusively. */

    rc = pthread_mutex_lock(&request_mutex);
 

#ifdef DEBUG

    printf("thread '%d' after pthread_mutex_lock\n", thread_id);

    fflush(stdout);

#endif /* DEBUG */
 

    /* do forever.... */

    while (1)

    {

#ifdef DEBUG

    	printf("thread '%d', num_requests =  %d\n", thread_id, num_requests);

    	fflush(stdout);

#endif /* DEBUG */

	if (num_requests > 0) { /* a request is pending */

	    a_request = get_request(&request_mutex);

	    if (a_request) { /* got a request - handle it and free it */

    		/* unlock mutex - so other threads would be able to handle */

		/* other reqeusts waiting in the queue paralelly.          */

    		rc = pthread_mutex_unlock(&request_mutex);

		handle_request(a_request, thread_id);

		free(a_request);

    		/* and lock the mutex again. */

    		rc = pthread_mutex_lock(&request_mutex);

	    }

	}

	else {

	    /* wait for a request to arrive. note the mutex will be */

	    /* unlocked here, thus allowing other threads access to */

	    /* requests list.                                       */

#ifdef DEBUG

    	    printf("thread '%d' before pthread_cond_wait\n", thread_id);

    	    fflush(stdout);

#endif /* DEBUG */

	    rc = pthread_cond_wait(&got_request, &request_mutex);

	    /* and after we return from pthread_cond_wait, the mutex  */

	    /* is locked again, so we don't need to lock it ourselves */

#ifdef DEBUG

    	    printf("thread '%d' after pthread_cond_wait\n", thread_id);

    	    fflush(stdout);

#endif /* DEBUG */

	}

    }

    return 0;

}

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 21782981
How do you know which request will be the last one?
0
 

Author Comment

by:4eyesgirl
ID: 21783025
Well,

The program I want to write is to process an input file, so I will know which one is the last record, correct?

Otherwise, what other method would you suggest me to do to terminate the thread?

The example you gave uses the nanosleep() in the main function which is not supported in windows.

Besides, I don't really want to uses sleep(), it doesn't really gurantee all working threads completed their tasks.

So one way I can think of is to mark the last request and once it is handling the last request, it singals all threads to terminate regardless they are in the while(1) loop or waiting for the pthread_cond_wait() function.  So what would you suggest me to do?
0
 
LVL 86

Expert Comment

by:jkr
ID: 21783110
>>The program I want to write is to process an input file, so I will know which
>>one is the last record, correct?

Yes, but I probably didn't ask the right thing - will one of the worker threads detect the last request or will you do that in the loop?
0
 

Author Comment

by:4eyesgirl
ID: 21783172
JKR -

I am start to think last request might not work also since the last record processed may not be the last one to get processed.

I guess I want to double check with you...do you see the issues I saw in the example you provided?

Basically, I want the program to handle requests using thread pool ...but I also need to ensure the job get done for each thread...the main program should be terminated when all requested are handled...

And if you look at the handle_request_loop() function, how does the thread know when to die?  The jobs could be done while the thread is still stuck in the pthread_cond_wait() call...

Can you let me know how would you change that program to accomplish what I am asking for?

0
 
LVL 86

Expert Comment

by:jkr
ID: 21783220
Stupid question - why not have the threads exit if e.g. 'num_requests' is set to a negative value (which you can do after processing all of them)? E.g.


        if (num_requests < 0) break; // terminate loop and exit thread
 

        if (num_requests > 0) { /* a request is pending */

            a_request = get_request(&request_mutex);

            if (a_request) { /* got a request - handle it and free it */

                /* unlock mutex - so other threads would be able to handle */

                /* other reqeusts waiting in the queue paralelly.          */

                rc = pthread_mutex_unlock(&request_mutex);

                handle_request(a_request, thread_id);

                free(a_request);

                /* and lock the mutex again. */

                rc = pthread_mutex_lock(&request_mutex);

            }

        }

        else {

            /* wait for a request to arrive. note the mutex will be */

            /* unlocked here, thus allowing other threads access to */

            /* requests list.                                       */

#ifdef DEBUG

            printf("thread '%d' before pthread_cond_wait\n", thread_id);

            fflush(stdout);

#endif /* DEBUG */

            rc = pthread_cond_wait(&got_request, &request_mutex);

            /* and after we return from pthread_cond_wait, the mutex  */

            /* is locked again, so we don't need to lock it ourselves */

#ifdef DEBUG

            printf("thread '%d' after pthread_cond_wait\n", thread_id);

            fflush(stdout);

#endif /* DEBUG */

        }

Open in new window

0
 

Author Comment

by:4eyesgirl
ID: 21789814
JKR -

Did you considered the below situation?

When the main thread successfully set the num_request to a negative number, the following condition can occrred.

Thread 1 is in pthread_cond_wait()
thread 2 is in pthread_cond_wait()
thread 3 is enter the if (num_requests < 0) break;  


In this case, only thread 3 is exit successfully...What about thread1 and thread2?  They are still in the pthread_cond_wait() condition...
0
 
LVL 86

Expert Comment

by:jkr
ID: 21814718
Sorry for the delay, missed the notification. Well, to prevent that, unlocking the mutex before exiting the thread should help.
0
 

Author Comment

by:4eyesgirl
ID: 21814838
Unlock the mutex?

Can you show me how to do it?  Right after

if (num_requests < 0){
pthread_mutex_unlock(&request_mutex);  --> Can this unlock both thread1 and thread2 pthread_cond_wait()?  I am unfamiliar with the pthread_cond_wait() call...please explains if this is wha tyou mean.
break;
}
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 21856602
'pthread_mutex_unlock(&request_mutex);' is pretty much what I had in mind. Since both threads are waiting for the mutex, that should be OK. Any problems with that approach while testing it?
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now