Threading error/questions

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,...)'



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <windows.h>
#include <time.h>
#include <iostream>

using namespace std;

void timer(int*);

int main()
   {
   int* time;
   (*time) = 300;       
   DWORD word;
   HANDLE handle;
   
   handle = CreateThread(NULL,
   0,
   timer,
   time,
   0,
   &word);
                         
   }


void timer(int* min)
   {                         
   time_t bSeconds, eSeconds;

   bSeconds = time(NULL);

   while(true)
      {
      eSeconds = time(NULL);
      if(eSeconds - bSeconds >= *min)
         {
         cout << "Time has expired!\n";
         system("pause"); 
         break;        
         }        
      }
   }


Can anyone tell me why i'm getting this error?
Also if anyone can explain the logic of threads to me that'd be great!

Thank You
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.
Ok i've changed the code around a bit but i'm still getting a similar error. I don't know what i'm missing.

invalid converstion from 'DWORD(*)(void*)' to 'DWORD(*)(void*)'
initializing argument 3 of...


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <windows.h>
#include <time.h>
#include <iostream>

using namespace std;

DWORD timer(void*);

int main()
   {       
   DWORD dw;
   HANDLE h;
   
   h = CreateThread(NULL,
   0,
   timer,
   0,
   0, 
   &dw);                   
   }


DWORD timer(void*)
   {     
   DWORD i;                    
   time_t bSeconds, eSeconds;

   bSeconds = time(NULL);

   while(true)
      {
      eSeconds = time(NULL);
      if(eSeconds - bSeconds >= 300)
         {
         cout << "Time has expired!\n";
         system("pause"); 
         i = true;
         return i;       
         }        
      }
   }


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...
Try passing &timer instead of timer to CreateThread().

The void * is so you can pass data to the thread.

http://en.wikipedia.org/wiki/DWORD (In short, it's a 32-bit unsigned integer.)
Last edited on
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...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream> 
#include <windows.h> 
#include <process.h>
#include <time.h> 
#include <string>

using namespace std; 
  
DWORD WINAPI ThreadProc(void* min) 
   {     
   time_t bSeconds, eSeconds;
   bSeconds = time(NULL);

   while(true)
      {
      eSeconds = time(NULL);
      if(eSeconds - bSeconds >= (int)min)
         {
         cout << "Time has expired!\n";
         //Performs actions here
         system("pause"); 
         break;     
         }        
      }
   _endthread(); 
   } 
      
int main() 
   {
   string input = "";
   HANDLE h;
   h = (HANDLE)CreateThread(NULL, 0, ThreadProc, (void*)15, 0, NULL); // create thread 
   
   cin >> input;
   cout << input;  
   system("pause"); 
   return 0; 
   } 


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?
(void*)15
[...]
(int)min
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.
It seems to defeat the purpose of keeping the two in seperate threads. They need to be independant of each other.
No, because you can't run code in the main() thread while receiving user input, so you can't check how much time has passed.
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?
Let me see if I get what you're trying to do:

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)).
Last edited on
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.
The easiest way to do it is add a bool to the passed struct
In other words,
1
2
3
4
5
struct param_struct{
	int time;
	std::string *input;
	bool kill;    
};
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!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream> 
#include <windows.h> 
#include <process.h>
#include <time.h> 
#include <string>

using namespace std; 

struct param_struct
   {
   int time;
   string* input;
   bool kill;    
   param_struct();  //Constructor
   };
   
param_struct::param_struct()
   {
   time = 10;
   kill = false;
   input = NULL;                         
   }
   
     
DWORD WINAPI ThreadProc(void* parameter)   //Thread 1
   {     
   time_t bSeconds, eSeconds;
   bSeconds = time(NULL);

   while(true)
      {
      if((*(param_struct*)parameter).kill == true)  //If kill value has been set to true, exit
         exit(1);
      eSeconds = time(NULL);           //If time has expired and no input found, exit
      if(eSeconds - bSeconds >= (*(param_struct*)parameter).time && (*(param_struct*)parameter).input == NULL)
         {
         //cout << (*(param_struct*)parameter).kill  << endl << (*(param_struct*)parameter).input << endl << (*(param_struct*)parameter).time << endl << endl;
         exit(1);    
         }
      }
   _endthread(); 
   } 
   
   
int main()   //Thread 0
   {
   string input = "";
   HANDLE h;
   param_struct* parameter = new param_struct();  //New param_struct object
   
   h = (HANDLE)CreateThread(NULL, 0, ThreadProc, parameter, 0, NULL); // Start thread 1
   cin >> input;  //get user input
   parameter->kill = true;  //Set kill value for Thread 1 to true
   (*parameter->input) = input;  //Store user input into struct
   
   cout << input;  
   system("pause");
   return 0; 
   } 


Much appreciated!
Use Sleep(DWORD) to wait milliseconds. A thread doesn't use CPU until Sleep() returns.
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?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream> 
#include <windows.h> 
#include <process.h>
#include <time.h> 
#include <string>

using namespace std; 

struct param_struct
   {
   int time;
   string input;
   bool kill;    
   param_struct();  //Constructor
   };
   
param_struct::param_struct()
   {
   time = 10;
   kill = false;
   input = "";                         
   }
   
     
DWORD WINAPI ThreadProc(void* parameter)   //Thread 1
   {     
   bool done = false;
   
   Sleep(10000);  //Sleep for 10 seconds
   cout << (*(param_struct*)parameter).kill  << endl << (*(param_struct*)parameter).input << endl << (*(param_struct*)parameter).time << endl << endl;
   if((*(param_struct*)parameter).kill == true)  //If kill value has been set to true, exit thread
      _endthread();
   if((*(param_struct*)parameter).input == "")   //If no input shut down program
      done = true;
   if(done)  
      exit(1);  //Exit program
   else
      _endthread();
   } 
   
   
int main()   //Thread 0
   {
   string input = "";
   HANDLE h;
   param_struct* parameter = new param_struct();  //New param_struct object
   
   h = (HANDLE)CreateThread(NULL, 0, ThreadProc, parameter, 0, NULL); // Start thread 1
   cin >> input;  //get user input
   parameter->kill = true;  //Set kill value for Thread 1 to true
   (*parameter).input = input;  //Store user input into struct
   cout << (*parameter).input;  
   system("pause");
   return 0; 
   }
Topic archived. No new replies allowed.