I'm trying to multi-thread a program i'm writing so it can accept user input while running a timer (so that if the user doesn't enter anything within a given time the program shuts down). I'm new to threading and don't really understand the logic. I've looked through the MSDN library but their examples seem complex and don't explain the process of starting one and stopping one or switching to another one etc. I've been writing code based on examples i've found just kinda hoping it'll work.
The following code is what i've written but I get an error as follows:
invalid conversion from 'void(*)(int*)' to 'DWORD(*)(void*)'
initializing argument 3 of 'void* CreateThread(_SECURITY_ATTRIBUTES*,DWORD,...)'
The error is pretty explicit. You're passing the function timer, which is a pointer to function that takes an int * and returns nothing, when the expected parameter is a pointer to a function that takes a void * and returns a DWORD.
So what exactly is DWORD supposed to be? What am i returning? I was told that this was optional but when i put NULL as the last argument to the 'CreateThread' function i get the same error...
That didn't fix it either. The error is on the line with the '&dw'
However I did manage to find some code online that i adapted to my purpose and it works but I need to get a little more functionality out of it...
So far what this does is print out "Time has expired" after 15 seconds. At the same time it allows the user to input data. What I need it to do is after 15 seconds check to see if the variable 'input' is NULL and if so perform a certain action...otherwise continue. How would I do that?
Sweet mother of God! Don't you ever do that again!
1 2 3 4 5 6 7 8 9 10 11
struct param_struct{
int time;
std::string *input;
};
DWORD WINAPI ThreadProc(void* param){
param_struct *data=(param_struct *)param;
//...
param_struct data={15,&input}; //I'm not feeling very creative with the names, am I?
h = (HANDLE)CreateThread(NULL, 0, ThreadProc, &data, 0, NULL);
lol sorry! I didn't realize that was bad...seemed logical to me. Anyway, I don't see how passing an object which includes the input helps. It seems to defeat the purpose of keeping the two in seperate threads. They need to be independant of each other. I was thinking more along the lines of doing the comparison after the timer has ended...
Somehow I need to end the timer thread after input has been entered or I need to do an immediate if statement after the timer ends that checks the status of the input.
Hmmm ok maybe i'm just not understanding it then. Cause it just seems to me that if i do that i'll wind up right where I am right now. Sorry to be a pain in the butt it's just not clicking. What if i were to create a second thread and pass it just the input? Would the timer thread and the input thread be able to see each other? What i'm thinking is if there's a way for one thread to end the other thread just have them run parallel and when one is done it ends the other. This would allow only one to actually run completely which would work perfectly.
On a side note,
What is the purpose of the HANDLE? meaning essentially what does CreateThread return and store into h?
thread0 (main()):
1. Start thread1.
2. Get user input.
3. Kill thread1.
thread1:
1. Wait n seconds.
2. Do something with 'input'.
3. Kill thread0 (i.e. terminate program, or exit(0)).
That's what you're trying to do, right?
HANDLEs are used by the WinAPI as generic pointers (they are void *, as a matter of fact) to identify system resources. They are used for practically everything: threads, processes, files, UI elements, etc.
Yes that's exactly what i'm trying to do. I was just going to use exit(1) to kill thread 0 but i'm not sure how to kill thread 1 from within thread 0 but if we can figure that out it should solve everything.
I don't think there's an API function to kill a thread, though I may be wrong. The easiest way to do it is add a bool to the passed struct:
thread0 (main()):
1. Start thread1.
2. Get user input.
3. Set bool to 1.
thread1:
1. Do 100*n times{ 1. Wait 10 milliseconds. 2. If bool return (ends thread).
}
2. Do something with 'input'.
3. Kill thread0 (i.e. terminate program, or exit(0)).
Ok, so I understand you're saying start the timer, get user input and set a flag indicating input has been gotten.
Now in thread 1 you want me to check a flag (which i assume is the one set after getting user input) every 10 milliseconds. I'm not clear on how thread 1 has access to the flag in thread 0 though.
Ok, I've looked at all of your suggestions and have again modified the code. It compiles with no errors but appears to get caught in an endless loop in thread 1 if i do any sort of input. On the other hand if i don't put in any input, it only exits the thread when i tell it to exit the program (exit(1)). Is it possible that exit(1) is only exiting the thread?
I was hoping you might be able to take a look at the code again and see if you notice anything that's wrong or why it might not be acting the way I want it to...It'd be an enormous help!
I tried Sleep(DWORD) and i get an error: expecting parameter before ) so it doesn't like it. I also tried doing it without a loop altogether. I have it sleep for 10 seconds and then check kill and input and shut down the program in certain cases. That didn't work either. It seems that in the timer thread, the code "exit(1)" doesn't shut down the program but only exits the thread. Is there other code i can use to shut down the entire program?