LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 12-22-2004, 01:05 AM   #1
ej25
Member
 
Registered: Nov 2004
Posts: 39

Rep: Reputation: 15
thread Synchronization


there is something wrong with my code. what's it?

Code:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

void* even_odd_sum(void*);
/* This is the lock for thread synchronization */
pthread_mutex_t    my_sync;

/* This is the condition variable */
pthread_cond_t    rx;
/* The global variables */
int cumulative_row_odd_sum=0;
int cumulative_row_even_sum=0;
int i,j,n1;
int count=0;




int main()
{
	int **matrix;
	int n,t;

	int i, j;
	pthread_t   tid;
	pthread_attr_t   attr;

/* Initialize the thread attributes */
	pthread_attr_init (&attr);

/* Initialize the mutex (default attributes) */
	pthread_mutex_init (&my_sync, NULL);

/* Initialize the condition variable (default attr) */
	pthread_cond_init (&rx, NULL);



	printf("Enter the value of n: ");
	scanf("%d", &n);
n=n1;
	matrix = (int **) malloc(n * sizeof(int *));
	for (i=0; i<n; i++) {
		matrix[i] = (int *) malloc(n * sizeof(int));
		for (j=0; j<n; j++) {
			printf("Enter number [%d,%d]: ", i, j);
			scanf("%d", &matrix[i][j]);
		}
	}


	/* put here your code */


	/* just test demo */
	printf("\n---------------------\n");
	for (i=0; i<n; i++) {
		for(j=0;j<n;j++)
			printf("%d\t", matrix[i][j]);
		printf("\n");
	}
//******************************************************************************
	for(t=0; t < n; t++)    {
         printf ("Creating thread %d\n", t);
         pthread_create (&tid, &attr, even_odd_sum ,matrix );
	}





//*****************************************************************************
	/* Finally free all memory */
	for (i=0; i<n; i++) 
		free(matrix[i]);
	free(matrix);
	exit(0);
}	

void* even_odd_sum (void* array){

	
pthread_mutex_lock(&my_sync);

for (i=0; i<n1; i++) {
		for(j=0;j<n1;j++){
			if(array[i][j]%2==0)
		cumulative_row_even_sum=cumulative_row_even_sum+array[i][j];
			else
				cumulative_row_odd_sum=cumulative_row_odd_sum+array[i][j];
			}
printf("the sum of even number in the %d row is %d\n",count,cumulative_row_even_sum);
printf("the sum of odd number in the %d row is %d\n",count,cumulative_row_odd_sum);
count++;
}

pthread_mutex_unlock(&my_sync);

sleep(1);
return;
}

it show me this error:


Code:
linux.ccse.kfupm.edu.sa> gcc p2.c -lpthread
p2.c: In function `even_odd_sum':
p2.c:84: warning: dereferencing `void *' pointer
p2.c:84: invalid use of void expression
p2.c:91: warning: dereferencing `void *' pointer
p2.c:91: void value not ignored as it ought to be
p2.c:92: warning: dereferencing `void *' pointer
p2.c:92: void value not ignored as it ought to be
p2.c:94: warning: dereferencing `void *' pointer
p2.c:94: void value not ignored as it ought to be
p2.c:106: parse error at end of input
linux.ccse.kfupm.edu.sa> gcc p2.c -lpthread
 
Old 12-22-2004, 02:15 AM   #2
bm17
Member
 
Registered: Sep 2004
Location: Santa Cruz, CA, USA
Distribution: Redhat 9.0
Posts: 104

Rep: Reputation: 15
You are passing in array as a (void *) to even_odd_sum(). Then you try to dereference it. It is as if you expect even_odd_sum to know that array is a multidimensional matrix because you passed the variable "matrix" to it. C does not work like this. C is a low-level language. Data objects do not keep type information with themselves. C data is not self-describing. By declaring the array parameter as a (void *) you are saying that you can handle that parameter no matter what type it is. Then you go on to use it as if it had the symantics that you invested in the variable "matrix" above.

This is the reason that C++ has such strong type checking; to avoid hacks like this. If you need to use this (void *) hack then you should take the burdon of type checking upon yourself and cast the "array" parameter into multi-dimentional array, or whatever nonsense it is that C uses.
 
Old 12-22-2004, 03:08 AM   #3
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris10, Solaris 11, Ubuntu, OEL
Posts: 9,165

Rep: Reputation: 243Reputation: 243Reputation: 243
Without arguing about C and C++ languages low-levelness virtues, your program has three bugs:
Code:
n=n1;
should be
Code:
n1=n;
Code:
void* even_odd_sum (void* array){
should be
Code:
void* even_odd_sum (void* _array){
int **array=(int**)_array;
and
Code:
return;
should be
Code:
return(NULL);
 
Old 12-22-2004, 03:54 AM   #4
shishir
Member
 
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251

Rep: Reputation: 33
and then some more...
he is not doing any pthread_join..so his thread might not get to run in the first place.....take care that you call pthread_join before you free the matrix in the main function...else you could end up with a lot of junk and head scratching

also, there is use of same tid for two threads....make an array of the number of threads you want to run....

...
 
Old 12-23-2004, 04:01 AM   #5
ej25
Member
 
Registered: Nov 2004
Posts: 39

Original Poster
Rep: Reputation: 15
Thanks men
it's work fine
 
Old 12-23-2004, 04:08 AM   #6
ej25
Member
 
Registered: Nov 2004
Posts: 39

Original Poster
Rep: Reputation: 15
now, I'm trying to let the thread first sum the even number of all rows and then sum the odd number for each row
using the conditional variable (count2)

Code:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

void* even_odd_sum(void*);
/* This is the lock for thread synchronization */
pthread_mutex_t    my_sync;

/* This is the condition variable */
pthread_cond_t    rx;
/* The global variables */
int cumulative_row_odd_sum=0;
int cumulative_row_even_sum=0;
int i=0;
int j,n1;
int count=0;
int count2=0;


int main()
{
	int **matrix;
	int n,t;

	int i, j;
	pthread_t   tid;
	pthread_attr_t   attr;

/* Initialize the thread attributes */
	pthread_attr_init (&attr);

/* Initialize the mutex (default attributes) */
	pthread_mutex_init (&my_sync, NULL);

/* Initialize the condition variable (default attr) */
	pthread_cond_init (&rx, NULL);



	printf("Enter the value of n: ");
	scanf("%d", &n);
n1=n;
	matrix = (int **) malloc(n * sizeof(int *));
	for (i=0; i<n; i++) {
		matrix[i] = (int *) malloc(n * sizeof(int));
		for (j=0; j<n; j++) {
			printf("Enter number [%d,%d]: ", i, j);
			scanf("%d", &matrix[i][j]);
		}
	}


	/* put here your code */

	/* just test demo */
	printf("\n---------------------\n");
	for (i=0; i<n; i++) {
		for(j=0;j<n;j++)
			printf("%d\t", matrix[i][j]);
		printf("\n");
	}
	printf("\n---------------------\n");
//******************************************************************************
	for(t=0; t < n; t++)    {
         printf ("Creating thread %d\n", t);
         pthread_create (&tid, &attr, even_odd_sum ,matrix );
	pthread_join(tid,NULL);
	}
	
printf("the final sum of even number is %d\n",cumulative_row_even_sum);
printf("the final sum of odd number is %d\n",cumulative_row_odd_sum);



//*****************************************************************************
	/* Finally free all memory */
	for (i=0; i<n; i++) 
		free(matrix[i]);
	free(matrix);
	exit(0);
}	

void* even_odd_sum (void* array){
int **array2=(int**)array;
	
		pthread_mutex_lock(&my_sync);
		while(count2<n1)
		pthread_cond_wait(&rx,&my_sync);
				i=0;	
			for(j=0;j<n1;j++){
			if(array2[i][j]%2!=0)
		cumulative_row_odd_sum=cumulative_row_odd_sum+array2[i][j];
				}
				i++;
			pthread_mutex_unlock(&my_sync);
			


		
			
			pthread_mutex_lock(&my_sync);
		while(count2<n1){
			for(j=0;j<n1;j++){
				if(array2[i][j]%2==0)
		cumulative_row_even_sum=cumulative_row_even_sum+array2[i][j];
		}
		count2++;
			i++;
			}
			if(count2 >= n1)
			pthread_cond_signal(&rx);			
			pthread_mutex_unlock(&my_sync);
			
						
			//to check if the operation goes well
		printf("the sum of even number in the %d row is %d\n",count,cumulative_row_even_sum);
		printf("the sum of odd number in the %d row is %d\n",count,cumulative_row_odd_sum);

count++;
			
		


sleep(1);
return (NULL) ;
}

but the program dosen't work now. I don't why!!!!!!!!!!!
Do you see any thing wrong ?
 
Old 12-23-2004, 05:28 AM   #7
shishir
Member
 
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251

Rep: Reputation: 33
try moving the two parts of the function into two different functions as you would be cond waiting on one part of the code and when your second thread runs it sees that it is waiting and hence never gets to the part that signals the condition...

if you want i can post the modified code..but it is better that you try on your own and see all the problems...
also ..you are printing the final values before the pthread_joins...
remember this ...pthread_join can be looked at as a wait for threads..so it basically forces the calling thread to wait for the child threads to complete execution...
once you are done ..then print the cummulative sums,,,else you might end up with 0's as sum...
HTH
 
Old 12-23-2004, 06:18 AM   #8
ej25
Member
 
Registered: Nov 2004
Posts: 39

Original Poster
Rep: Reputation: 15
Quote:
try moving the two parts of the function into two different functions
I want it to be in the same function. I know it is easier to make it separate.


Quote:
you are printing the final values before the pthread_joins
you mean what I'm printing in the function?
if yes, this only to check if its steps work fine (debug)
 
Old 12-23-2004, 07:30 AM   #9
shishir
Member
 
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251

Rep: Reputation: 33
then in that case you might have to use the goto: why...here you go..
when the first thread runs..it blocks on a condition...so you'd have to perform a check when you enter the function again as it is gonna try locking the lock that has been locked already by the thread 1, so to get around that problem, either use recursive lock ..in which event you'd have to unlock as many times as you lock it...or use a goto to jump to the code that is containing the code for performing the second half of processing and also signalling the condition....
 
Old 12-23-2004, 09:31 AM   #10
ej25
Member
 
Registered: Nov 2004
Posts: 39

Original Poster
Rep: Reputation: 15
I didn't get it.

Quote:
try locking the lock that has been locked already by the thread 1
you mean in the second part of the function, I should use "goto" (new thing for me!!!!!)
because in the first part the wait will work as automatic unlock (as I know)
 
Old 12-23-2004, 12:25 PM   #11
shishir
Member
 
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251

Rep: Reputation: 33
i mean try somethin like:
Code:
if ( pthread_self() != TID_FIRST_THREAD)
     goto LABEL;
while(count2<n1)
            pthread_cond_wait.....and so on
            .
            .
            pthread_mutex_unlock(&my_sync);


LABEL:
          	pthread_mutex_lock(&my_sync);
                .
                .
        	if(count2 >= n1)
        		pthread_cond_signal(&rx);			
                 ..and so on..
this will work..why? because otherwise your second(later) thread also gets blocked at the same spot as the first thread...at pthread_cond_wait..and because it is waiting for someone to signal the condition (something you expect the second or later threads to do...) , the cond. wont get triggered and hence your thread gets stuck at the cond_wait...

..that is why..it is better that you separate the thread functions....cos anyway you are having two threads and hence two invocations of the function...with each hving its own stack...that would just make it a lot cleaner and easier to understand...

HTH

PS: forget about the recursive locking part..m,y mistake..i totally forgot about the unlocking performed by pthread_cond_wait...long time since i used these things...


Last edited by shishir; 12-23-2004 at 12:27 PM.
 
Old 12-24-2004, 08:41 AM   #12
ej25
Member
 
Registered: Nov 2004
Posts: 39

Original Poster
Rep: Reputation: 15
I try your way but it seem to be not work. only the first thread work and the second enter the infinite wait

Code:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

void* even_odd_sum(void*);
/* This is the lock for thread synchronization */
pthread_mutex_t    my_sync;

/* This is the condition variable */
pthread_cond_t    rx;
/* The global variables */
int cumulative_row_odd_sum=0;
int cumulative_row_even_sum=0;
int i=0;
int j,n1;
int count=0;
int count2=0;
int TID_First_Thread;

int main()
{
	int **matrix;
	int n,t;

	int i, j;
	pthread_t   tid;
	pthread_attr_t   attr;

/* Initialize the thread attributes */
	pthread_attr_init (&attr);

/* Initialize the mutex (default attributes) */
	pthread_mutex_init (&my_sync, NULL);

/* Initialize the condition variable (default attr) */
	pthread_cond_init (&rx, NULL);



	printf("Enter the value of n: ");
	scanf("%d", &n);
n1=n;
	matrix = (int **) malloc(n * sizeof(int *));
	for (i=0; i<n; i++) {
		matrix[i] = (int *) malloc(n * sizeof(int));
		for (j=0; j<n; j++) {
			printf("Enter number [%d,%d]: ", i, j);
			scanf("%d", &matrix[i][j]);
		}
	}


	/* put here your code */

	/* just test demo */
	printf("\n---------------------\n");
	for (i=0; i<n; i++) {
		for(j=0;j<n;j++)
			printf("%d\t", matrix[i][j]);
		printf("\n");
	}
	printf("\n---------------------\n");
//******************************************************************************
	for(t=0; t < n; t++)    {
         printf ("Creating thread %d\n", t);
         pthread_create (&tid, &attr, even_odd_sum ,matrix );
	 
	 TID_First_Thread = pthread_self();
	
	 
	 
	pthread_join(tid,NULL);
	}
	
printf("the final sum of even number is %d\n",cumulative_row_even_sum);
printf("the final sum of odd number is %d\n",cumulative_row_odd_sum);



//*****************************************************************************
	/* Finally free all memory */
	for (i=0; i<n; i++) 
	free(matrix[i]);
	free(matrix);
	exit(0);
}	

void* even_odd_sum (void* array){
int **array2=(int**)array;
count2++;	
if (pthread_self() != TID_First_Thread)
goto L1;

		pthread_mutex_lock(&my_sync);
		
		pthread_cond_wait(&rx,&my_sync);
				i=0;	
			for(j=0;j<n1;j++){
			if(array2[i][j]%2!=0)
		cumulative_row_odd_sum=cumulative_row_odd_sum+array2[i][j];
				}
				i++;
			pthread_mutex_unlock(&my_sync);
			


		L1:
			
			pthread_mutex_lock(&my_sync);
		
			for(j=0;j<n1;j++){
				if(array2[i][j]%2==0)
		cumulative_row_even_sum=cumulative_row_even_sum+array2[i][j];
		}
		
			i++;
			
			if(count2 > n1){
			pthread_cond_signal(&rx);			
			pthread_mutex_unlock(&my_sync);}
			
						
			//to check if the operation goes well
		printf("the sum of even number in the %d row is %d\n",count,cumulative_row_even_sum);
		printf("the sum of odd number in the %d row is %d\n",count,cumulative_row_odd_sum);

count++;
			
		


sleep(1);
return (NULL) ;
}

Last edited by ej25; 12-24-2004 at 08:42 AM.
 
Old 12-24-2004, 01:11 PM   #13
shishir
Member
 
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251

Rep: Reputation: 33
there are a couple of problems with your code..
1: you are not givin the var:TID_First_Thread the tid of first thread but the tid of the 'main()' thread...it would be a good idea to have an array of tids and assigning this variable value:tid[0].

2: in the thread function you have removed the condition on which it is waiting,,,add the code..although the code will run as the wait will be broken by a cond_signal from the later thread..
..rest your code is fine..move the pthread_join's out of the thread creation loop....you dont want the parent thread to start waiting and hence block and not create any more threads...

i hope this does it for you...

Last edited by shishir; 12-24-2004 at 01:12 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
clock synchronization rasejo Linux - General 12 07-12-2007 06:53 PM
email synchronization (not file synchronization) Moebius Linux - Software 6 10-05-2004 05:31 AM
Main thread sending notification to child thread rajesh_b Programming 1 09-22-2004 09:15 AM
configure qt thread issue (just compiled qt w/ -thread option) cleff Linux - Software 8 05-07-2004 11:11 PM
synchronization of monitor dark_light Linux - General 1 07-23-2002 08:55 PM


All times are GMT -5. The time now is 05:35 AM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration