#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;
}
Related
#include <iostream>
#include <queue>
#include <thread>
#include <process.h>
#include <windows.h>
#include <stdlib.h>
int g_Width = 100;
std::queue<std::vector<unsigned short>> BufferQueue;
bool dataRead = false;
unsigned short* g_pImgBuf = NULL;
unsigned int _stdcall Write(void* arg) {
std::vector<unsigned short> data;
data.reserve(g_Width);
int line = 0;
while (dataRead)
{
if (!dataRead)
break;
for (int i = 0; i < g_Width; i++) {
data.push_back(i);
}
BufferQueue.push(data);
data.clear();
}
_endthreadex(0);
return 0;
}
unsigned int _stdcall Read(void* arg) {
std::vector<unsigned short> data;
data.reserve(g_Width);
unsigned short color = 0;
int line = 0;
while (dataRead)
{
g_pImgBuf = new unsigned short[g_Width];
if (!BufferQueue.empty()) {
data = BufferQueue.front();
BufferQueue.pop();
}
else if (!dataRead)
break;
else {
continue;
}
for (int j = 0; j < g_Width; j++) {
color = data[j];
color += 2;
g_pImgBuf[j] = color;
}
data.clear();
}
if (g_pImgBuf) { free(g_pImgBuf); g_pImgBuf = NULL; }
_endthreadex(0);
return 0;
}
int main()
{
dataRead = true;
HANDLE r_hThread = NULL;
unsigned r_threadID;
r_hThread = (HANDLE)_beginthreadex(NULL, 0, Read, NULL, 0, &r_threadID);
HANDLE w_hThread = NULL;
unsigned w_threadID;
w_hThread = (HANDLE)_beginthreadex(NULL, 0, Write, NULL, 0, &w_threadID);
while (true)
{
Sleep(100);
}
}
The following error occurred
vector subscript out of range 1501 error
In the middle of the thread function
Give it sleep (2) and it works sometimes but soon I get an error.
If the vector is the problem, is there any other way to store the array in the queue?
I don't know where the problem is
Is there a good way?
You simply cannot do this in such a simplistic way. If you want one thread to pick messages off the queue that are being written by another thread you need mtuexes and condition variables. This is not a trivial task. I suggest a lot of googling. I will look too and updat here if I find a good link
https://juanchopanzacpp.wordpress.com/2013/02/26/concurrent-queue-c11/
https://gist.github.com/ictlyh/f8473ad0cb1008c6b32c41f3dea98ef5
I am newer for c++, and I know in c++0x multithreading support is poor.
But now I have to edit a string val in multi thread, I use thread_mutex to protect the val. The problem is the program always core dump when runing.
Although after re-design I find a better solution but I can't figure out why it core. So could some one told me about what happend?
The code is like below
using namespace std;
const static int kThreadSize = 48;
map<string, string> gMap;
string gStr = "";
void * func(void * data)
{
while(true)
{
printf("%s\n", gStr.c_str());
pthread_mutex_t m;
pthread_mutex_init(&m, NULL);
pthread_mutex_lock(&m);
gStr = gStr + "a";//core in this line
printf("%x\n", &gStr);//print the address
pthread_mutex_unlock(&m);
pthread_mutex_destroy(&m);
printf("%s\n", gStr.c_str());
}
}
int main()
{
pthread_t threads[kThreadSize];
for(int i = 0; i < kThreadSize; i ++)
{
pthread_create(&threads[i], NULL, &func, &gMap);
}
for(int i = 0; i < kThreadSize; i ++)
{
pthread_join(threads[i], NULL);
}
return 0;
}
EDIT:
By using the global mutex will solve the problem pointed by Mike.Here I don't paste the new source code.
My new question is I also can't understand why it will core when edit a string in multithreading. Because of COW or reference count?
As i can see there is a problem with yours Mutex, because it is create into the method func() and it make that each thread invocation of func()create a new mutex, it is happened by each threat that invokes this method.
As MikeB says, i sugest you review the thread theory but, meanwhile, try to use a unique mutex to synchronize the access to gMap, as the example shows:
using namespace std;
const static int kThreadSize = 48;
map<string, string> gMap;
string gStr = "";
pthread_mutex_t m;
void * func(void * data)
{
while(true)
{
printf("%s\n", gStr.c_str());
pthread_mutex_lock(&m);
gStr = gStr + "a";//core in this line
printf("%x\n", &gStr);//print the address
pthread_mutex_unlock(&m);
printf("%s\n", gStr.c_str());
}
}
int main()
{
pthread_mutex_init(&m, NULL);
pthread_t threads[kThreadSize];
for(int i = 0; i < kThreadSize; i ++)
{
pthread_create(&threads[i], NULL, &func, &gMap);
}
for(int i = 0; i < kThreadSize; i ++)
{
pthread_join(threads[i], NULL);
}
return 0;
}
I have the test code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_t th_worker, th_worker2;
void * worker2(void *data) {
for(int i = 0; i< 1000000; i++){
printf("thread for worker2----%d\n", i);
usleep(500);
}
}
void * worker(void *data){
pthread_create(&th_worker2, NULL, worker2, data);
for(int i = 0; i< 100; i++){
printf("thread for worker-----%d\n", i);
usleep(500);
}
}
void join(pthread_t _th){
pthread_join(_th, NULL);
}
In main() function, If I call join(the_worker2):
int main() {
char* str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void*) str);
/* problem in here */
join(th_worker2);
return 1;
}
--> Segment Fault error
Else, i call:
join(the_worker);
join(th_worker2);
---> OK
Why have segment fault error in above case?
Thanks for help !!!
If you posted all your code, you have a race condition.
main is synchronized with the start of worker but not worker2.
That is, main is trying to join th_worker2 before worker has had a chance to invoke pthread_create and set up th_worker2 with a valid [non-null] value.
So, th_worker2 will be invalid until the second pthread_create completes, but that's already too late for main. It has already fetched th_worker2, which has a NULL value and main will segfault.
When you add the join for th_worker, it works because it guarantees synchronization and no race condition.
To achieve this guarantee without the join, have main do:
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
while (! th_worker2)
usleep(100);
/* problem in here */
join(th_worker2);
return 1;
}
An even better way to do this is to add an extra variable. With this, the first loop is not needed [but I've left it in]:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int worker_running;
pthread_t th_worker;
int worker2_running;
pthread_t th_worker2;
void *
worker2(void *data)
{
// tell main we're fully functional
worker2_running = 1;
for (int i = 0; i < 1000000; i++) {
printf("thread for worker2----%d\n", i);
usleep(500);
}
return NULL;
}
void *
worker(void *data)
{
// tell main we're fully functional
worker_running = 1;
pthread_create(&th_worker2, NULL, worker2, data);
for (int i = 0; i < 100; i++) {
printf("thread for worker-----%d\n", i);
usleep(500);
}
return NULL;
}
void
join(pthread_t _th)
{
pthread_join(_th, NULL);
}
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
// NOTE: this not necessarily needed as loop below is better
while (! th_worker2)
usleep(100);
// give worker2 enough time to completely start
while (! worker2_running)
usleep(100);
/* problem in here (not anymore!) */
join(th_worker2);
return 1;
}
Like my title says, I'm trying to modify the CreateThread function. I want it to report the sequence number of the thread using the loop.
I'm fairly new to programming in C++ and am unsure which parameter needs to be altered. I suspect it may be the 'lpParameter' but after looking on microsofts website (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx) I still do not understand how the parameters work.
So far I have:
int int_tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread[numThreads];
int tNum[10];
for (int i = 0; i < numThreads; i++)
{
tNum[i] = i;
hThread[i] =
CreateThread(NULL, 0, helloFun, NULL, 0, NULL);
} WaitForMultipleObjects(numThreads, hThread, TRUE, INFINITE);
return 0;
}
Which produces a blank thread.
EDIT:
Sorry for the confusion guys. I have declared the thread routine:
const int numThreads = 4;
DWORD WINAPI helloFun(LPVOID pArg)
{
printf("Hello Thread \n");
return 0;
}
It's not clear what you are trying to do, but it is clear that you are calling WaitForMultipleObjects in the wrong place.
You are trying to wait for numThreads after only creating one thread. The rest of the hThread array is still uninitialized, and passing wild handles to WaitForMultipleObjects is a terrible idea.
Move the wait call outside the loop.
Your thread routine must be declared
DWORD name (LPVOID whatever)
Whatever is passed as lpParameter is passed to the thread. In this case, cast integer to pointer and back.
As you mentioned, if you want to pass a parameter to the thread, then you use the lpParameter. It expects a pointer, so you could pass, for instance, &i, although that's not exactly a good idea. You could create a pointer to int, and pass it, and then delete after WaitForMultipleObjectsreturns.
As Ben said, you are calling WaitForMultipleObjects in the wrong place.
Something like this should work:
int int_tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread[numThreads];
int tNum[10];
int *parameters[numThreads];
for (int i = 0; i < numThreads; i++)
{
tNum[i] = i;
parameters[i] = new int(i);
hThread[i] = CreateThread(NULL, 0, helloFun, (void *)parameters[i], 0, NULL);
}
WaitForMultipleObjects(numThreads, hThread, TRUE, INFINITE);
for (int i = 0; i < numThreads; i++)
delete parameters[i];
return 0;
}
You will have to cast the lpParameter to int in your helloFun.
Try something more like this:
const int maxThreads = 4;
DWORD WINAPI helloFun(LPVOID pArg)
{
int num = * (int*) pArg;
printf("Hello from Thread %d\n", num);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread[maxThreads];
int tNum[maxThreads];
int numThreads = 0;
for (int i = 0; i < maxThreads; i++)
{
tNum[numThreads] = i+1;
hThread[numThreads] = CreateThread(NULL, 0, &helloFun, &tNum[numThreads], 0, NULL);
if (hThread[numThreads] == NULL)
{
printf("Unable to create a thread! Error: %u\n", GetLastError());
break;
}
++numThreads;
}
if (numThreads > 0)
{
WaitForMultipleObjects(numThreads, hThread, TRUE, INFINITE);
for (int i = 0; i < numThreads; i++)
CloseHandle(hThread[i]);
}
return 0;
}
I am reading a message from a socket with C++ code and am trying to plot it interactively with matplotlib, but it seems Python code will block the main thread, no matter I use show() or ion() and draw(). ion() and draw() won't block in Python.
Any idea how to plot interactively with matplotlib in C++ code?
An example would be really good.
Thanks a lot.
You may also try creating a new thread that does the call to the
blocking function, so that it does not block IO in your main program
loop. Use an array of thread objects and loop through to find an unused
one, create a thread to do the blocking calls, and have another thread
that joins them when they are completed.
This code is a quick slap-together I did to demonstrate what I mean about
using threads to get pseudo asynchronous behavior for blocking functions...
I have not compiled it or combed over it very well, it is simply to show
you how to accomplish this.
#include <pthread.h>
#include <sys/types.h>
#include <string>
#include <memory.h>
#include <malloc.h>
#define MAX_THREADS 256 // Make this as low as possible!
using namespace std;
pthread_t PTHREAD_NULL;
typedef string someTypeOrStruct;
class MyClass
{
typedef struct
{
int id;
MyClass *obj;
someTypeOrStruct input;
} thread_data;
void draw(); //Undefined in this example
bool getInput(someTypeOrStruct *); //Undefined in this example
int AsyncDraw(MyClass * obj, someTypeOrStruct &input);
static void * Joiner(MyClass * obj);
static void * DoDraw(thread_data *arg);
pthread_t thread[MAX_THREADS], JoinThread;
bool threadRunning[MAX_THREADS], StopJoinThread;
bool exitRequested;
public:
void Main();
};
bool MyClass::getInput(someTypeOrStruct *input)
{
}
void MyClass::Main()
{
exitRequested = false;
pthread_create( &JoinThread, NULL, (void *(*)(void *))MyClass::Joiner, this);
while(!exitRequested)
{
someTypeOrStruct tmpinput;
if(getInput(&tmpinput))
AsyncDraw(this, tmpinput);
}
if(JoinThread != PTHREAD_NULL)
{
StopJoinThread = true;
pthread_join(JoinThread, NULL);
}
}
void *MyClass::DoDraw(thread_data *arg)
{
if(arg == NULL) return NULL;
thread_data *data = (thread_data *) arg;
data->obj->threadRunning[data->id] = true;
// -> Do your draw here <- //
free(arg);
data->obj->threadRunning[data->id] = false; // Let the joinThread know we are done with this handle...
}
int MyClass::AsyncDraw(MyClass *obj, someTypeOrStruct &input)
{
int timeout = 10; // Adjust higher to make it try harder...
while(timeout)
{
for(int i = 0; i < MAX_THREADS; i++)
{
if(thread[i] == PTHREAD_NULL)
{
thread_data *data = (thread_data *)malloc(sizeof(thread_data));
if(data)
{
data->id = i;
data->obj = this;
data->input = input;
pthread_create( &(thread[i]), NULL,(void* (*)(void*))MyClass::DoDraw, (void *)&data);
return 1;
}
return 0;
}
}
timeout--;
}
}
void *MyClass::Joiner(MyClass * obj)
{
obj->StopJoinThread = false;
while(!obj->StopJoinThread)
{
for(int i = 0; i < MAX_THREADS; i++)
if(!obj->threadRunning[i] && obj->thread[i] != PTHREAD_NULL)
{
pthread_join(obj->thread[i], NULL);
obj->thread[i] = PTHREAD_NULL;
}
}
}
int main(int argc, char **argv)
{
MyClass base;
base.Main();
return 0;
}
This way you can continue accepting input while the draw is occurring.
~~Fixed so the above code actually compiles, make sure to add -lpthread