I wrote some test code like this which compiled and worked fine...
void threadtest()
{
HANDLE hThrd;
DWORD threadId;
int i;
for (i = 0;i < 5;i++)
{
hThrd = CreateThread(
NULL,
0,
ThreadFunc,
(LPVOID)i,
0,
&threadId );
}
// more stuff
}
DWORD WINAPI ThreadFunc(LPVOID n)
{
// stuff
return 0;
}
Then I wanted to modify the code to put the ThreadFunc inside a class and then declare an array of those classes. I thought the code should look like this:
class thread_type
{
public:
DWORD WINAPI ThreadFunc(LPVOID n)
{
// stuff
return 0;
}
};
void threadtest()
{
HANDLE hThrd;
DWORD threadId;
int i;
thread_type *slave;
slave = new thread_type[5];
for (i = 0;i < 5;i++)
{
hThrd = CreateThread(
NULL,
0,
slave[i].ThreadFunc,
(LPVOID)i,
0,
&threadId );
}
// more stuff
}
Unfortunately the compiler complains about the line slave[i].ThreadFunc, I think I may need some special casting but all the permutations I try involving "::" and "&" seem to fail (I'm quite new to C++). The real code has some additional complications which I haven't included for clarity, but I think they are irrelevant.
First problem with the code, that the test class is not descendant of the thread_type. Somehow you need to specify the base class.
Second is, if you are passing function pointer, that shouldn't be thiscall type. The solution is typically this:
struct thread
{
virtual void
run() = 0;
static thread_func(void* param)
{
thread* pThread = (thread*)param;
thread->run();
}
}
struct worker : public thread
{
void
run()
{
(.. code for the thread...)
}
}
void threadtest()
{
HANDLE hThrd;
DWORD threadId;
int i;
thread *slave;
slave = new thread_type[5];
slave[0] = new worker;
slave[1] = new worker;
slave[2] = new worker;
slave[3] = new worker;
slave[4] = new worker;
for (i = 0;i < 5;i++)
{
hThrd = CreateThread(
NULL,
0,
&thread::thread_func,
(LPVOID)slave[i],
0,
&threadId );
}
// more stuff
}
Note that this could is just a reflection, I couldn't compile now, because I don't have here anything to do so, but the logic should be like this.
The following explains the difference between a pointer to a function and a pointer to a member function C++ FAQ Lite. See section 33.2 which explains why what you are doing is a bad idea.
Related
(Note before starting: Although my question is general, my code needs to compile with legacy Visual Studio 2008 MFC application and has to use MFC or win32 synchronization, please avoid answers using ie boost or c++ 11)
I am trying to implement a Thread Safe Pipe (A Queue with a single reader and a single writer), I did the following:
template<class T>
class CMultiThreadPipe {
private:
HANDLE hSemaphore, hTerminateEvent1, hTerminateEvent2;
CRITICAL_SECTION listMutex;
CList<T*, T*> list;
public:
CMultiThreadPipe() {
InitializeCriticalSection(&listMutex);
hSemaphore = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
hTerminateEvent1 = ::CreateEvent(NULL, TRUE, FALSE, NULL);
hTerminateEvent2 = ::CreateEvent(NULL, TRUE, FALSE, NULL);
}
// pdata must be allocated with new. The dequeueing thread will delete it
void Enqueue(T* pdata) {
EnterCriticalSection(&listMutex);
list.AddHead(pdata);
LeaveCriticalSection(&listMutex);
ReleaseSemaphore(hSemaphore, 1, NULL);
}
// if Dequeue returns null it means the pipe was destroyed and no further queue method calls are legal
// Dequeue caller is responsible to delete the returned instance
T* Dequeue()
{
HANDLE handles[] = { hTerminateEvent1, hSemaphore };
DWORD waitRes = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
if (waitRes==WAIT_OBJECT_0) {
SetEvent(hTerminateEvent2);
return NULL; // terminated
}
EnterCriticalSection(&listMutex);
T* elem = list.RemoveTail();
LeaveCriticalSection(&listMutex);
return elem; // handler must delete item
}
void Destroy() {
SetEvent(hTerminateEvent1);
WaitForSingleObject(hTerminateEvent2, INFINITE);
EnterCriticalSection(&listMutex);
POSITION pos = list.GetHeadPosition();
for (int i = 0; i < list.GetCount(); i++) delete list.GetNext(pos);
LeaveCriticalSection(&listMutex);
DeleteCriticalSection(&listMutex);
CloseHandle(hSemaphore);
}
~CMultiThreadPipe() {
Destroy();
}
};
The code is used like this:
class QueueData {
public:
QueueData(int i) : m_data(i) {};
int m_data;
};
UINT DequeueThreadProc(LPVOID dummy);
CMultiThreadedPipe<QueueData>* pPipe = NULL;
void main() {
pPipe = new CMultiThreadedPipe<QueueData>();
start new thread running DequeueThreadProc
int counter=0;
for (int counter=0; counter<10; counter++)
{
pPipe->Enqueue(new QueueData(counter));
Sleep(300);
}
delete pPipe;
}
UINT DequeueThreadProc(LPVOID ignore)
{
QueueData* queueData;
while ((queueData = pPipe->Dequeue()) != NULL) {
delete queueData;
Sleep(1000);
};
return 0;
}
The issue I have is with termination, in the above implementation, when the pipe is destroyed (always by the enqueing thread) it is waiting for the dequeing thread to know that it terminated before deleting the queue. It has to do that to prevent a situation where the dequeing thread tries to dequeue after the pipe is destroyed.
If the dequeing thread does not keep calling dequeue the first thread will hang in the destructor, also if the dequeing thread waits a long time between calls to dequeue the destructor of the first thread will get stuck there accordingly.
I read various posts about it none mentions safe destruction. Any help appreciated !
for safe destruction object, which accessed from multiple threads you need use reference counting on it. before pass object pointer to new thread - you increment reference on object. when thread no more using object, or if create thread fail, you decrement reference count. when last reference on object released - you can safe call destructor for object. and you not need here wait for any threads.
also for implement such queue - in windows exist special object - named I/O Completion Ports in user space (in kernel space in know as KQUEUE). with this object - implementation will be more efficient and simply - you not need manage self list (CList in your code), synchronize access to it - all this will be done in kernel space for you (PostQueuedCompletionStatus -> KeInsertQueue, GetQueuedCompletionStatus -> KeRemoveQueue). you need create only iocp, (kqueue) object.
class CMultiThreadPipe {
public:
class __declspec(novtable) QueueData {
public:
virtual void ProcessItem() = 0;
virtual ~QueueData()
{
DbgPrint("%x: %s<%p>\n", GetCurrentThreadId(), __FUNCTION__, this);
}
QueueData()
{
DbgPrint("%x: %s<%p>\n", GetCurrentThreadId(), __FUNCTION__, this);
}
};
private:
HANDLE _hIOCP;
LONG _dwRef;
ULONG _nThreads;
void DequeueThreadProc()
{
ULONG NumberOfBytesTransferred;
QueueData* pData;
OVERLAPPED* pOverlapped;
while (GetQueuedCompletionStatus(_hIOCP,
&NumberOfBytesTransferred,
(ULONG_PTR*)&pData,
&pOverlapped, INFINITE))
{
if (pData)
{
pData->ProcessItem();
}
else
{
break;
}
}
Release();
}
__declspec(noreturn) static DWORD CALLBACK _DequeueThreadProc(PVOID pThis)
{
reinterpret_cast<CMultiThreadPipe*>(pThis)->DequeueThreadProc();
FreeLibraryAndExitThread((HMODULE)&__ImageBase, 0);
}
~CMultiThreadPipe()
{
if (_hIOCP)
{
CloseHandle(_hIOCP);
}
}
public:
CMultiThreadPipe() : _dwRef(1), _hIOCP(0)
{
}
void AddRef()
{
InterlockedIncrement(&_dwRef);
}
void Release()
{
if (!InterlockedDecrement(&_dwRef))
{
delete this;
}
}
ULONG Create(DWORD NumberOfDequeueThreads)
{
if (_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, NumberOfDequeueThreads))
{
ULONG n = 0;
do
{
HMODULE hModule;
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (PCWSTR)_DequeueThreadProc, &hModule))
{
AddRef();
if (HANDLE hThread = CreateThread(0, 0, _DequeueThreadProc, this, 0, 0))
{
CloseHandle(hThread);
n++;
}
else
{
Release();
FreeLibrary(hModule);
}
}
} while (--NumberOfDequeueThreads);
_nThreads = n;
return n ? NOERROR : ERROR_GEN_FAILURE;
}
return GetLastError();
}
ULONG Enqueue(QueueData* pData)
{
return PostQueuedCompletionStatus(_hIOCP, 0, (ULONG_PTR)pData, 0) ? NOERROR : GetLastError();
}
void Destroy()
{
if (ULONG n = _nThreads)
{
do
{
PostQueuedCompletionStatus(_hIOCP, 0, 0, 0);
} while (--n);
}
}
};
and usage:
class QueueData : public CMultiThreadPipe::QueueData
{
int m_data;
virtual void ProcessItem()
{
DbgPrint("%x: %s<%p>(%u)\n", GetCurrentThreadId(), __FUNCTION__, this, m_data);
delete this;
}
public:
QueueData(int i) : m_data(i) {};
};
void testQueue()
{
if (CMultiThreadPipe* pPipe = new CMultiThreadPipe)
{
if (pPipe->Create(8) == NOERROR)
{
int n = 64;
do
{
if (QueueData* pData = new QueueData(n))
{
if (pPipe->Enqueue(pData))
{
delete pData;
}
}
} while (--n);
pPipe->Destroy();
}
pPipe->Release();
}
}
note with such CMultiThreadPipe implementations - you not need wait when working threads exit. even if your code inside dll and you unload dll - you not need wait. every thread have own reference for object and module. and release it on exit
I want to call a function with multiple threads, and I only need to pass a single integer to that function (the thread id, so if it is accessible I need no value to pass).
How should I do this?
for example like:
for(int i=0; i < numberOfThread; i++ ){
pthread_create(&threads[i], NULL, multichaper, &td[i]);
}
in which multichaper is my function and threadID is an integer.
Update: I marked the answer from user3286661 as the right answer and that worked for me, if you want a more detailed answer you can check my own solution to this question in answers.
General approach to this is to make the function like this:
void* multichaper(void* arg) {
int tid = *(int*)arg;
...
}
And while calling pthread_create:
pthread_create(&threads[i], NULL, multichaper, &td[i])
where td[i] is an int.
You really should consider moving to C++11 threads:
#include <thread>
#include <iostream>
void show_id(int id) {
std::cout << id << std::endl;
}
int main()
{
std::thread t(show_id, 10);
t.join();
}
If you must use pthreads, though:
#include <iostream>
#include <pthread.h>
void *show_id(void *x_void_ptr)
{
const int id = *static_cast<int *>(x_void_ptr);
std::cout << id << std::endl;
return NULL;
}
int main()
{
pthread_t t;
int id = 10;
if(pthread_create(&t, NULL, show_id, &id)) {
std::cerr << "couldn't create" << std::endl;
return -1;
}
if(pthread_join(t, NULL)) {
std::cerr << "couldn't join" << std::endl;
return -2;
}
}
Note how much better the first version is:
No casts
Fewer explicit checks
No problem with the lifetime of the object you're passing - in the first version, you're passing a pointer to it, and thus must ensure it's "alive" while the thread is using it.
No unintuitive void * returns (with the same lifetime problems).
No. You can't do that. The function you pass to pthread_create must have the signature void *(*start_routine) (void *). That is, a function taking a non-const pointer to void and returning a non-const pointer to void.
The simplest way is something like:
int *arg = new int(threadID);
pthread_create(&threads[i], NULL, multichaper, threadID );
and then multichaper looks like:
void *multichaper(void *arg)
{
int *pint = static_cast<int*>(arg);
int threadID = *pint;
delete pint;
...
return nullptr;
}
Note that I have allocated the int on the heap to avoid having to worry about variable lifetimes. If you can guarantee that the variable threadID in the calling function will outlive the thread, then you can skip that bit.
I strongly recommend you use C+11 and the built-in threading library, or if you can't do that, use boost::threads. They both make this much easier!
As i want to pass numbers from 0 to NumberOfThreads to my function i finally used the code below, by passing an integer inside a struct and locking (lock_mutex) that when trying to retrieve the threadNum:
Calling function in multi threads in a member function of SVAnchor class:
pthread_t threads[this->numberOfThread];
pthread_attr_t attr;
params_t params;
pthread_mutex_init (¶ms.mutex , NULL);
pthread_cond_init (¶ms.done, NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for(int i=0; i < this->numberOfThread; i++ ){
params.id = i;
params.ptr = this;
rc = pthread_create(&threads[i], NULL, &(SVAnchor::multichaperWrapper), ¶ms);
pthread_cond_wait (¶ms.done, ¶ms.mutex);
}
pthread_attr_destroy(&attr);
void* status;
for(int i=0; i < this->numberOfThread; i++ )
rc = pthread_join(threads[i], &status);
pthread_mutex_destroy (¶ms.mutex);
pthread_cond_destroy (¶ms.done);
with params_t as follows:
struct params {
SVAnchor* ptr;
pthread_mutex_t mutex;
pthread_cond_t done;
int id;
};
typedef struct params params_t;
and then multichaperWrapper is as follows:
void* SVAnchor::multichaperWrapper(void* arg){
return (((params*)arg)->ptr)->multichaper( ((params*)arg));
}
and multichaper is as follows:
void* SVAnchor::multichaper( void *threadarg /*0 <= threadNum < numberofthreads*/ ){
int threadNum;
/* Lock. */
pthread_mutex_lock(&(*(params_t*)(threadarg)).mutex);
/* Work. */
threadNum = (*(params_t*)(threadarg)).id;
/* Unlock and signal completion. */
pthread_mutex_unlock(&(*(params_t*)(threadarg)).mutex);
pthread_cond_signal (&(*(params_t*)(threadarg)).done);
cout<<threadNum<<endl;
...
}
If all you want to do is pass an id to the calling thread you can do so by burying it in the void* parameter, and do so portably. Like,
pthread_create(&threads[i], NULL, multichaper, (void*)threadID );
I'm trying to get my Main Program to start a thread that manages a section of my program... The thread that gets made creates a sub thread for each element of an array. The sub thread sets the array element to not available, delays by 10 seconds, and then sets the element to available. The main thread, however, continues normal execution until the array element is available.
However, it doesn't seem to apply a delay...
Please note the array is a global array.
What am I doing wrong?
The below code will outline what I want better then the explanation...
DWORD WINAPI SubThread(void* lpParam)
{
int i = (int)lpParam;
printf("Sub Thread Ran");
structureArray[i].available= false;
Sleep(10000);
structureArray[i].available = true;
return 0;
}
DWORD WINAPI MainThread(void * lpParam)
{
while(true)
{
for(int i = 0; i < structureArray.size(); i++)
{
if(structureArray[i].available)
{
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SubThread, (LPVOID)i, 0, NULL);
}
}
}
}
Your global variable is not thread safe, it seems.
Try using a thread safe collection or lock the access yourself (solution is windows specific, inferred from your WINAPI specifier):
class CriticalSection
{
public:
CriticalSection()
{ ::InitializeCriticalSection(&m_cs); }
~CriticalSection()
{ ::DeleteCriticalSection(&m_cs); }
void Enter()
{ ::EnterCriticalSection(&m_cs); }
void Leave()
{ ::LeaveCriticalSection(&m_cs); }
private:
// private to prevent copying
CriticalSection(const CriticalSection&);
CriticalSection& operator=(const CriticalSection&);
CRITICAL_SECTION m_cs;
};
class Lock
{
public:
Lock(CriticalSection& a_section): m_section(a_section)
{ m_section.Enter(); }
~Lock()
{ m_section.Leave(); }
private:
Lock(const CSLock&);
Lock& operator=(const CSLock&);
CriticalSection& m_section;
};
CriticalSection g_dontUseGlobalCS;
DWORD WINAPI SubThread(void* lpParam)
{
int i = (int)lpParam;
printf("Sub Thread runs for...");
Sleep(10000);
{ // use scope to destroy lock...
Lock(g_dontUseGlobalCS);
structureArray[i].available= true;
} // exactly here
// note: a new thread could already be running here
// for debugging purposes add this:
printf("10 seconds.");
return 0;
}
DWORD WINAPI MainThread(void * lpParam)
{
while(true)
{
for(int i = 0; i < structureArray.size(); i++)
{
Lock(g_dontUseGlobalCS);
if(structureArray[i].available)
{
// set the thread availability here
structureArray[i].available = false;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SubThread, (LPVOID)i, 0, NULL);
}
}
}
}
I also moved the set of the availability flag to the creator thread. Usually you would use other mechanisms to realize what you are trying to do:
Look into windows synchronization functions or wiki
#include <stdio.h>
#include <process.h>
#include <wtypes.h>
typedef unsigned int (__stdcall * THREAD_FUN_TYPE)(void *);
int ThreadIp(void* param)
{
while(true)
{
printf("I'm runing!\n");
}
return 0;
}
int main()
{
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
phThreads[i]=(HANDLE*)_beginthreadex(NULL, 0, (THREAD_FUN_TYPE)ThreadIp,NULL, NULL, NULL);
}
int nIndex = ::WaitForMultipleObjects(iThreadNum,phThreads,1,INFINITE);
printf("End!\n");
return 0;
}
I want the program will halt at WaitForMultipleObjects until all thread are end(Not until all thread are created successfully).But the program will not halt at WaitForMultipleObjects,while all threads are still running. So I try to use SetEvent,but still the same problem:
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
phThreads[i]=CreateEvent(NULL, FALSE, FALSE,NULL);
ResetEvent(phThreads[i]);
}
int nIndex = ::WaitForMultipleObjects(iThreadNum,phThreads,1,INFINITE);
You should wait on the thread handles, not the unrelated events:
Try something like this:
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
m_iCurThreadNum=i;
phThreads[i] = _beginthreadex(...);
}
int nIndex = ::WaitForMultipleObjects(iThreadNum,phThreads,1,INFINITE);
Does it work if you have fewer threads? The manual says you need to do extra work if you have more than MAXIMUM_WAIT_OBJECTS, specifically
nCount [in] The number of object handles in the array pointed to by
lpHandles. The maximum number of object handles is
MAXIMUM_WAIT_OBJECTS. This parameter cannot be zero.
See here for a discussion.
It might be worth checking what the wait function has returned too.
I would allocate a struct before calling _beginthreadex and pass the pointer to the struct through the threads parameter and have the struct contain a bool which is set by the thread when it's done.
struct ThreadStruct{
bool Done;
char* ParamData;
int ParamDataSize;
};
int ThreadIp(void* param)
{
ThreadStruct* ts = (ThreadStruct*)param;
while(true)
{
printf("I'm runing!\n");
}
ts->Done = true;
return 0;
}
int main()
{
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
ThreadStruct* structs = new ThreadStruct[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
ZeroMemory(structs[i], sizeof(ThreadStruct));
phThreads[i]=(HANDLE*)_beginthreadex(NULL, 0, (THREAD_FUN_TYPE)ThreadIp, structs[i], NULL, NULL);
ResetEvent(phThreads[i]);
}
for(unsigned int i=0; i<iThreadNum;){
if(!structs[i]->Done) i=0;
else i++;
}
printf("End!\n");
return 0;
}
Below I have an int main() and two header files, one of which is a class for creating a thread and another which is a class called object that gets created within the windows_thread class. This really simple exercise should output 99 but instead its 1 (for some unknown reason). I also tried using a pointer to an object made by new which crashed when void call() from the function Thread_no_1( ) to the class object is made, maybe because its none existent. I hope someone could remedy this otherwise I'll just use windows threads in int main().
this is the main.
#include "windows_thread.h"
int main()
{
windows_thread* THREAD = new windows_thread();
THREAD->thread();
delete THREAD;
return 0;
}
this is the windows_thread.h
#include <windows.h>
#include <stdio.h>
#include "object.h"
#define BUF_SIZE 255
class windows_thread
{
object OBJECT;
public:
windows_thread():OBJECT(99)
{
//OBJECT = new object(99);
}
~windows_thread()
{
//delete OBJECT;
}
void thread()
{
std::cout<<"void thread: "<<std::endl;
int Data_Of_Thread_1 = 1; // Data of Thread 1
HANDLE Handle_Of_Thread_1 = 0; // variable to hold handle of Thread 1
HANDLE Array_Of_Thread_Handles[1]; // Aray to store thread handles
// Create thread 1.
Handle_Of_Thread_1 = CreateThread( NULL, 0, Wrap_Thread_no_1, &Data_Of_Thread_1, 0, NULL);
if ( Handle_Of_Thread_1 == NULL) ExitProcess(Data_Of_Thread_1);
// Store Thread handles in Array of Thread Handles as per the requirement of WaitForMultipleObjects()
Array_Of_Thread_Handles[0] = Handle_Of_Thread_1;
// Wait until all threads have terminated.
WaitForMultipleObjects( 1, Array_Of_Thread_Handles, TRUE, INFINITE);
printf("Since All threads executed lets close their handles \n");
// Close all thread handles upon completion.
CloseHandle(Handle_Of_Thread_1);
}
void DisplayMessage (HANDLE hScreen, char *ThreadName, int Data, int Count)
{
TCHAR msgBuf[BUF_SIZE];
size_t cchStringSize;
DWORD dwChars;
// Print message using thread-safe functions.
//StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Executing iteration %02d of %s having data = %02d \n"), Count, ThreadName, Data);
//StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hScreen, msgBuf, cchStringSize, &dwChars, NULL);
Sleep(1000);
}
DWORD WINAPI Thread_no_1( )
{
std::cout<<"Thread_no_1: "<<std::endl;
OBJECT.call();
//OBJECT->call();
return 0;
}
static DWORD WINAPI Wrap_Thread_no_1( LPVOID lpParam )
{
std::cout<<"Wrap_Thread_no_1: "<<std::endl;
windows_thread *self = reinterpret_cast<windows_thread*>(lpParam);
self->Thread_no_1();
return 0;
}
};
next is the object.h
#ifndef OBJECT_H
#define OBJECT_H
#include <iostream>
class object
{
private:
int value;
public:
object(int value)
{
std::cout<<"object::constructor: "<<std::endl;
this->value = value;
}
~object(){}
void call()
{
std::cout<<"object::call(): begin"<<std::endl;
std::cout<<value<<std::endl;
std::cout<<"object::call(): end"<<std::endl;
}
};
#endif
This function call:
Handle_Of_Thread_1 = CreateThread(
NULL,
0,
Wrap_Thread_no_1,
&Data_Of_Thread_1, // <== THIS IS A POINTER TO AN int
0,
NULL
);
Passes &Data_Of_Thread_1 (a pointer to an int) to CreateThread(). This is the argument that gets eventually passed to Wrap_Thread_no_1().
Inside that function, you then cast that pointer to a windows_thread* and call a member function through it. This injects Undefined Behavior in your code.
You probably meant to do this instead:
Handle_Of_Thread_1 = CreateThread(NULL, 0, Wrap_Thread_no_1, this, 0, NULL);
// ^^^^