ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
#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
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.
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....
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 ?
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
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....
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)
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...
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) ;
}
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...
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.