• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 244
  • Last Modified:

Why don't values in my structs stay when I assign values to them?

if I had the following files with the following code:
#######################################################
A.h
---

#ifndef A_H
#define A_H
#include <semaphore.h>
typedef struct {
  char *name;
  int value;
} structOne;

int funciton_1(structOne *mutex);

int function_2(structOne *mutex);

#endif


########################################################
A.c
---
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>

#include "A.h"


int function_1(structOne *mutex)
{
  mutex->value = 1;
  return 0;
}

########################################################
program.c
---------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#include "circ_buffer.h"
#include "A.h"

static char *message = "A Message";

static const unsigned int SIZE = 5;
static circ_buffer_t cb;

static void *producer(void *arg);
static void *consumer(void *arg);

structOne mutex;    

int main(void)
{
   int i;
   pthread_t PID, CID;    //define the producer and consumer threads
    void *junk;

   function_1(&mutex);  //SETS 'value' TO 1 within the struct

   circ_buffer_init(&cb, SIZE);  //initialize a circular buffer to SIZE
       
   pthread_create(&PID, NULL, producer, junk);
   pthread_create(&CID, NULL, consumer, junk);
   

  /*****joins threads together*****/
  pthread_join(PID, NULL);
  pthread_join(CID, NULL);

  /****clean up****/
  function_destroy(&mutex); // forgot to include this in the header 'A.h' but it should be there (basically it destorys the semaphore)
  pthread_exit(NULL);

  circ_buffer_destroy(&cb);
  return 0;
}


int function_1(structOne *mutex)
{
  if (mutex->value > 1)  // HERE's THE PROBLEM... I can't do this for some reason, I get the address or some big integer number not the '1' I previously set this value to in my main function.  This is the same for all the other comparisons with 'mutex->value'
    {
      ...    
    }

  if (mutex->value == 1)
    {
      mutex->mutexValue--;
    }
  else if (mutex->mutexValue == 0)
    {
      ...
    }
 
  return 0;
}


So basically what am I doing wrong?  I want the struct to retain the value I assigned it in main so that I can do some comparisons in subsequent functions.
0
CBMLude
Asked:
CBMLude
  • 3
  • 3
  • 2
  • +2
1 Solution
 
helmet275Commented:
did you initialize mutex?  You might type calling your parameters to your functions something other than the name of your global variable.  
0
 
gotenksCommented:
is this correct anyway, cos i see two function_1() in your code.

int main() {
   ...
   function_1(&mutex);

   return 0;
}

i see no mistake for this if you use the function_1() declared in A.c
but if you are using the second function_1() {the one below the main() }, then you won't be getting 1 cos you haven't initialize the mutex.value yet.
or have i overlook somewhere?
0
 
CBMLudeAuthor Commented:
oops... sorry the last function should be
int function_2(structOne *mutex)
{

}
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
CBMLudeAuthor Commented:
argh... sorry.. I messed up again... that function
'function_2(structOne *mutex)' should be in file 'A.c'

and in file: program.c, there should be another function called
void *producer(void *arg)
{
   function_2(*arg);
}

Here's the entire thing again so it's doens't look hard to read it:

if I had the following files with the following code:
#######################################################
A.h
---

#ifndef A_H
#define A_H
#include <semaphore.h>
typedef struct {
 char *name;
 int value;
} structOne;

int funciton_1(structOne *mutex);

int function_2(structOne *mutex);

#endif


########################################################
A.c
---
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>

#include "A.h"


int function_1(structOne *mutex)
{
 mutex->value = 1;
 return 0;
}

int function_2(structOne *mutex)
{
if (mutex->value > 1)  // HERE's THE PROBLEM... I can't do this for some reason, I get the address or some big integer number not the '1' I previously set this value to in my main function.  This is the same for all the other comparisons with 'mutex->value'
   {
     ...    
   }

 if (mutex->value == 1)
   {
     mutex->mutexValue--;
   }
 else if (mutex->mutexValue == 0)
   {
     ...
   }
 
 return 0;
}

########################################################
program.c
---------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#include "circ_buffer.h"
#include "A.h"

static char *message = "A Message";

static const unsigned int SIZE = 5;
static circ_buffer_t cb;

static void *producer(void *arg);

structOne mutex;    

int main(void)
{
  int i;
  pthread_t PID, CID;    //define the producer and consumer threads
   void *junk;

  function_1(&mutex);  //SETS 'value' TO 1 within the struct

  circ_buffer_init(&cb, SIZE);  //initialize a circular buffer to SIZE
     
  pthread_create(&PID, NULL, producer, junk);
  pthread_create(&CID, NULL, consumer, junk);
   

 /*****joins threads together*****/
 pthread_join(PID, NULL);
 pthread_join(CID, NULL);

 /****clean up****/
 function_destroy(&mutex); // forgot to include this in the header 'A.h' but it should be there (basically it destorys the semaphore)
 pthread_exit(NULL);

 circ_buffer_destroy(&cb);
 return 0;
}


void *producer(void *arg)
{
   function_2(&mutex);
}


So basically what am I doing wrong?  I want the struct to retain the value I assigned it in main so that I can do some comparisons in subsequent functions.
0
 
KocilCommented:
Don't use the junk, use this instead.

pthread_create(&PID, NULL, producer, &mutex);
pthread_create(&CID, NULL, consumer, &mutex);
0
 
jcaldwelCommented:
Why are you reinventing mutex? What functionality do you need that POSTIX Thread Mutexes don't provide?

0
 
gotenksCommented:
hmm, still could not see any mistake though.
maybe you should try to do what Kocil suggested and rewrite your producer function to this :

void * producer (void * arg) {
   function_2((structOne *)arg);
   ...
}

int main() {
   ...
   pthread_create(&PID, NULL, producer, &mutex);
   ...
}

hope this will help?
0
 
KocilCommented:
The reason why don't use junk is because junk is allocated in the stack, while mutex is in data segment.

This is the more elegant solution

StructOne mutex;

main()
{
 ...
 pthread_create(&PID, NULL, consumer, (void*) &mutex);
 ...
}

void consumer(void *arg)
{
  StructOne *mutex = (StructOne*) arg;

  /* you may use the local mutex pointer */
  ...

}
0
 
CBMLudeAuthor Commented:
Kocil:
actually that wasn't the problem, for some reason if I changed the arguement for the prototypes in file 'A.c' to int function_1(structOne *m) and int function_2(structOne *m) it worked.

BUT..... after I assign the value: 'm->value = 1' (in function_1) and in function_2 try to access m->value I get '1' when the first thread tries to access that value.  When a 2nd thread gets into function_2, m->value is no longer 0 or 1 (depending if I did anything to it when the first thread got there first), it's a LARGE integer again, and I don't know what that is (probably the address I'm assumming).  Why is that?


jcaldwel:
I don't fully understand the usage of semaphores, and I've looked around online and found many places with sample code on how to rewrite semaphores with pthreads, I assume you can do it the other way around.  Besides playing around with this stuff is the best way to learn it.
0
 
KocilCommented:
Yea you right, it is better
void consumer(StructOne *mutex)
{
 /* you may use the local mutex pointer */
 ...
}

LARGE because it haven't initialized. It can be anything.
So I think you have to make sure that thread producer gets to the mutex first, maybe the main() can sleep for a while after creating the producer.
Another options is to initialize the mutex on main() before creating the threads.

Cheers

0

Featured Post

Get Certified for a Job in Cybersecurity

Want an exciting career in an emerging field? Earn your MS in Cybersecurity and get certified in ethical hacking or computer forensic investigation. WGU’s MSCSIA degree program was designed to meet the most recent U.S. Department of Homeland Security (DHS) and NSA guidelines.  

  • 3
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now