 |
|
 |
The first bug is the pthread_cond_destroy used 2 times inside the stop function and into the destructor In linux generate some problems on close
the second bug is how is used pthread_cond_wait
For the standard POSIX before calling pthread_cond_wait the mutex MUST BE LOCKED. then released, but this is not done
so
pthread_cond_wait(Thread::get_threadpool().get_object(), &m_mutex);
must be
pthread_mutex_lock(&am_mutex); pthread_cond_wait(Thread::get_threadpool().get_object(), &m_mutex); pthread_mutex_unlock(&m_mutex);
There is also a problem for this code (may be considerd a bug or not)
Consider to has a thread pool of only 1 thread that is doing all jobs into the queue inside the while.
while (pjob != NULL) { pjob->execute(pjob->data); pjob = get_threadpool().get_next(); }
when all jobs are done the thread exit from the while and and go into wait status
if (!get_threadpool().wait_thread()) { break; }
If an addjob is performed after the while status but before the thread go into the wait status the wait, the weak-up signal is missed and the job remain on queue until next signal. the problem is that the wait status is not atomically to the release of m_cs mutex. In order to resolve the problem m_mutex must be used to syncronize add_job and get_next and not another mutex m_cs, m_mutex is the only mutex that can be used to release the mutex and go into wait status atomically
Modify is a little difficult to explain but is not difficult to do.....
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
FOR WHO WANT COMPILE INTO LINUX I has compiled on linux, there are some little modifications (sorry for my english)
1) process.h is not a POSIX on linux is not needed (comment or use #ifndef to mantain portability ) 2) pthread.h don' t define PTHREAD_H but _PTHREAD_H ( define it yourself or modify all PTHREAD_H into _PTHREAD_H_ ) 3) #pragma once don' t work on linux (are ignored) use instead #ifndef XXXXX_H #define XXXXX_H
......................
#endif
( You can comment pragma once or enclose pragma into #ifndef as you like portability is mantained in both situation, in the second compiler is stressed more )
4) defines.h include pthread.h and define _PTHREAD_H
so modify
#ifndef PTHREAD_H #include "windows.h" #endif
#include #include #include "defines.h"
into
#include "defines.h" #ifndef PTHREAD_H #include "windows.h" #endif
#include #include
or g++ will try to include windows.h into linux (same thing is you use #ifndef for problem 1 defines.h must included before any #ifndef or #ifdef _PTHREAD_H)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi i trying ti compile the source as static lib but im getting this errors:
\thread.h(11) : error C2143: syntax error : missing ';' before '&' \threadpoollib\thread.h(11) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int \threadpoollib\thread.h(11) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int \threadpoollib\thread.h(11) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int thread.h(11) : warning C4183: 'get_threadpool': missing return type; assumed to be a member function returning 'int'
any idea why ?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
ok i found it , i guess vs 8 is more restrict any way you need to add foreword declaration in the threadpool.h to class Thread; and in thread.h add foreword declaration to class ThreadPool; dont forget to remove the #include "threadpool.h" hope that helps ...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
I'm a bit befuddled... 'I have NOT compiled this on Linux yet.' How can you claim the article is for a technology that you have not even tested?
Jeff
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
The technology is available on both Windows and Linux. I have tested with the pthreads API quite extensively on Windows. This is not a product, but a reference implementation.
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
 |
Hi I test your code on g++ 4.2.3 and It don't compile yet : thread.h: In static member function static ThreadPool& Thread::get_threadpool()â: thread.h:23: error: aggregate ThreadPool m_threadsâ has incomplete type and cannot be defined
I didn't solve the problem, can you help me?
Thx a lot leso
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Looks like this has been aluded to on an earlier thread, but as there has been no update for some time, I though I should alert people to this:
Each Thread instance is using its own mutex, but what should happen is all access to the condition variable should be serialised with a mutex shared across all threads. I added another mutex to the ThreadPool class and then wrapped calls to pthread_cond_wait and pthread_cond_signal with mutex locks/unlock.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
 |
I can use zThread in static library mode, but can't use it in dynamic mode. Who can help me?
Thanks in advance.
|
| Sign In·View Thread·PermaLink | 2.00/5 (2 votes) |
|
|
|
 |
|
 |
After compiling the program, it couldn't link because of the error message, "cannot open file "pthreadVC.lib".
Because there is a "pthreadVC.dll", will I have to create a "pthreadVC.lib" folder and move the '.dll' file to it, or is there another way to eliminate the link error message?
Thanks.
William
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
No, in the VC++
go to Tools | Options | Directories and
add the include and lib folders for the pthread library there.
Say you installed pthreads in C:\pthreads. I assume you will have c:\pthreads\include c:\pthreads\lib
add the include folder in the "Include" section and the lib folder in the "Library" section
Thomas
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
There are no "Include" and "Library" files (or folders) downloaded (for this application) for me to refer to. Consequently, I don't know what is there for me to add to Tools->Options->Directories (etc.).
There is this one file, "pthreadVC.dll" which looks like it might belong in a ".lib" folder, which is what my original question was about.
Even though I appreciate your suggestion about putting the "include" file in the "Include" section of Tools->Options->Directories, I usually reserve doing something like that for "includes" and libraries that I use very frequently to almost continuously. Applications that I use only on special occasions tends to overcrowd those sections if I were to add their individual entries for all of them (meaning, for the more than 100 such applications I have, adding their individual "include" and library entries in those sections hardly make any sense if I only use them once a month, or once every six months, etc.)
Anyway, thanks for the suggestion. I appreciate it.
Should there have been a library and "Include" folders downloaded from the demo version when I did that? I didn't get any!!
William
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Thank you for the information. It truly exemplifies the spirit of CodeProject.
Hope to return the favor one day to you. 
William
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi Thomas, I've been testing your CThreadPool class in order to use it in an academic project I'm working on. My question is: after the execute method finished is job I call the base class execute() method as you said to do. When the application ends I call the method CThreadPool::stop() and here is the problem i get an Unhandled exception because is trying to delete the job that was deleted before in the call to the CThreadJob::execute(). Is this a bug? Is it a problem in my app? Please I apreciate your help. The project I opened inthe VC is a win32 console application empty.
Thank you, António Serra.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I will check this out. I have not encountered this before. and I am using this in many of my applications.
Thanks
Thomas
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
 |
I noticed in the job processing code that in the case of pthreads you loop until the job queue is empty. With W32, you only process one.
Why the difference?
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
| Sign In·View Thread·PermaLink | 4.40/5 (2 votes) |
|
|
|
 |
|
 |
The behavior conditional variable in pthreads is equivalent to an event in Win32. In case of Win32 events, if you do a 'PulseEvent' call, the call does not do anything, if there are no threads waiting for it at that instant. So, a number of queued jobs will be lost.
But, IOCompletion port ensures that one thread will be woken up for every call of PostQueuedCompletionStatus, irrespective of whether there was a thread waiting on GetQueuedCompletionStatus at the instant of the call or not.
If I replace the IOCompletionPort with an event object, use the WaitForSingleObject instead of the GetQueuedCompletionStatus and use PulseEvent instead of PostQueuedCompletionStatus, then the code will be the same in both cases ie, the looping one.
But, since I had the working IOCompletionPort pool, I did not experiment on the other one.
Ideally, I would have liked to use defines only to map the API calls (as I did for the CRITICAL_SECTION), but the IOCompeltion ports could not be mapped directly due to additional parameters in the calls.
Thomas George
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Ah, thanks for the info. I will add IO completion ports to my list of neat little tools looking for an application. 
I use the CreateEvent (auto reset)/SetEvent style. Which of course requires that you purge the queue just in case you get 2 SetEvents prior to a thread waits for the event. Personally, I would be very scared of PulseEvent. Seems to be very risky with regards to losing event triggers.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
The pthread_cond_signal in pthreads is equivalent to PulseEvent in behaviour and is the only API call to wake up a thread based on a condition.
Ofcourse, if you are doing work specific to NT4 and above solely for Win32, ICCompletionPort is the ideal choice. It works very well.
If you noticed, it can wake up on a list of handles. All you have to do is to call CreateIOCompletionPort with each of the handles. The handles can be file handles, sockets, named pipes, events etc. Initially I used that mechanism for my server, but it was OS-specific and hence switched to using select, which works on all platforms.
Now, I am looking for a database API, that works on the Unix/Linux OSs and can be encapsulated into a class like this to switch between OLEDB and that.
Thomas George
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
The pthread_cond_signal in pthreads is equivalent to PulseEvent in behaviour and is the only API call to wake up a thread based on a condition.
????
I must have missed the boat on this whole condition variable stuff. I see no condition semantics in PulseEvent. Given the significant limitations, I have to admit I don't understand why it even exists.
If you have any links to applications where PulseEvent is better than SetEvent, I would LOVE to see them.
To be perfectly honest, I have been doing MT programming for nearly 15 years and have never even used any formal condition variables (anything beyond signaling an event.) But I am always willing to learn something new. (Well, if you kick me enough I am...)
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I am not suggesting that PulseEvent is better than SetEvent or is more suitable for any purpose.
Let me clarify the condition variable part first. The equivalent of events in pthreads API is called condition variables, meaning that based on the state/condition of that variable, threads wake up.
Now coming back to the reason why I mentioned PulseEvent,
I was merely stating that the pthread_cond_signal in pthreads library behaves similar to PulseEvent in Win32 API than any other Win32 API call.
In the pthreads API, to do the equivalent of
CreateEvent WaitForSingleObject WaitForMultipleObjects SetEvent ResetEvent PulseEvent
etc,...,
they have
pthread_cond_init - initialize a condition variable pthread_cond_wait - wait on a condition variable pthread_cond_signal - signal a condition variable to wake up one thread (this is the only call that can wake up one thread) pthread_cond_broadcast - wake up all threads waiting on the condition variable.
Now, The pthread_cond_signal does nothing when no threads are waiting on the condition object, similar to the behaviour of PulseEvent, where as SetEvent maintains the event signalled until a thread is available and is released.
So, if there has to be one to one mapping of the functions, pthread_cond_signal would be mapped to PulseEvent rather than SetEvent because SetEvent will always cause a thread to be released, where as PulseEvent or pthread_cond_signal does not.
Thomas George
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thank you. I understand what you are saying now.
(a.k.a. The Fog Lifts)
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Unfortunately, what he's saying isn't quite correct. An event object is a very simple synchronization concept, while a condition variable is a loose coupling of some shared state, a mutex and the "condition variable" which allows for notifications. The usage of all three components at once insures correctness. Any attempt to use an event in conjunction with any state data will result in a race condition. So a condition variable can be used any time you'd use an event, but you can't always use an event when you could use a condition variable. Their uses are different.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Yes, I know the differences between condition variables and events. In the context of our discussion, the condition part of the condition variable isn't being used.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |