Problems with C Runtime Thread

Hi guys, i am new to this forum and this is my first post. I am trying to create a timer and as i know almost nothing about threads, as usual got stuck. Can some one point out what i am doing wrong plz ??
here is the code that worx
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
61
62
63
64
65
66
67
68
69
70
#include <stdio.h>
#include <time.h>
#include <process.h>
#include <stdlib.h>
#include <windows.h>

struct timer_info{
	int interval ;
	void (*function)(void) ;
} ;

int hour, min, sec ;
HANDLE thread_id ;

void watch()
{
        sec++ ;
	if (sec > 59){
		min++ ;
		sec = 0 ;
	}
	if (min > 59){
		hour++ ;
		min = 0 ;
	}
	if (hour > 23)
		hour = 0 ;
	system("cls") ;
	printf("%02d : %02d : %02d\n", hour, min, sec) ;
	
}

void timer(void *info)
{
	while(1){
		clock_t begin = clock() ;
		while (clock() - begin  < 1000) ;
		watch() ;
	}

}

void set_timer()
{
	thread_id=(HANDLE)_beginthread(timer, 0, NULL) ;	
}

void init_watch(int &h, int &m, int &s)
{
	time_t init_data ;
	struct tm *ltime ;
	time(&init_data) ;
	ltime = localtime(&init_data) ;
	h = ltime->tm_hour ;
	m = ltime->tm_min ;
	s = ltime->tm_sec ;
}

int main()
{
	
	init_watch(hour, min, sec) ;
	printf("%02d : %02d : %02d\n", hour, min, sec) ;
	set_timer() ;
	WaitForSingleObject(thread_id, 1000000000) ;
	

	return 0 ;
}


and here is the one that doesn't and keeps crashing.
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
61
62
63
64
65
66
67
68
69
70
71
72
#include <stdio.h>
#include <time.h>
#include <process.h>
#include <stdlib.h>
#include <windows.h>

struct timer_info{
	int interval ;
	void (*function)(void) ;
} ;

int hour, min, sec ;
HANDLE thread_id ;

void watch()
{
	sec++ ;
	if (sec > 59){
		min++ ;
		sec = 0 ;
	}
	if (min > 59){
		hour++ ;
		min = 0 ;
	}
	if (hour > 23)
		hour = 0 ;
	system("cls") ;
	printf("%02d : %02d : %02d\n", hour, min, sec) ;
	
}

void timer(void *info)
{
	struct timer_info *t = (struct timer_info*)info ;
	int interval = t -> interval ;
	
	void (*func)(void) = t -> function ;
	while(1){
		clock_t begin = clock() ;
		while (clock() - begin  < 1000) ;
		func() ;
	}
}

void set_timer(int interval, void (*func)(void))
{
	struct timer_info info = {interval, func} ;
	thread_id = (HANDLE)_beginthread(timer, 0, (void*)&info) ;	
}

void init_watch(int &h, int &m, int &s)
{
	time_t init_data ;
	struct tm *ltime ;
	time(&init_data) ;
	ltime = localtime(&init_data) ;
	h = ltime->tm_hour ;
	m = ltime->tm_min ;
	s = ltime->tm_sec ;
}

int main()
{
	init_watch(hour, min, sec) ;
	printf("%02d : %02d : %02d\n", hour, min, sec) ;
	set_timer(1000, watch) ;
	WaitForSingleObject(thread_id, 1000000000) ;
	
	return 0 ;
}


it is interesting that when i try to print the value of t->interval in the timer(void*) function it becomes 1000000000 which should be 1000. c'mon where is the catch ?? thanx in advance :D
Have you tried running this in a debugger? You can help yourself by developing debugging skills.

Your program crashes because set_timer creates a local info, which is passed to the thread function as a parameter. But it goes out of scope when set_timer completes. The memory is probably reused by the next function, WaitForSingleObject, so the values of the memory locations are changed.

When your timer thread starts running, it picks out the values passed in and stores them locally. In your case, the values are already changed because WaitForSingleObject was called first. Your func address now points to oblivion and causes the crash when you call it.

If the timer thread got going before WaitForSingleObject was called, it would work. In instances such as this where the behaviour is determined by a race to given bits of code, we call a race condition.

Also, use
WaitForSingleObject(thread_id, INFINITE);
rather than
WaitForSingleObject(thread_id, 1000000000);
Last edited on
wow...super cool. Thanx :D. I guess i need to be more careful.
Like dealing with pointers, being careful isn't enough to be safe with multi-threading. You need good safe practices.
Topic archived. No new replies allowed.