From: Vandana on
Hello All,

First of all,I am very thankful to all the members who helped me
with my previous post on the same subject.

I have a shared memory (in the form of the struct shown below )between
2 process, and a member of the struct (child_inst) is being updated by
both the parent & child process. I use a mutex whenever a process is
modifying it. This modification happens several times when my program
is being run.

But, when I print this value out, I see that sometimes, it prints out
garbage values. Is this because sometimes, the mutex is not being
acquired by the modifying process? If this is the case, can you please
tell me a better way to do it or if it is better to use spinlocks?

I have the following shared memory struct in the header

struct sync_core_shared {
int parent_inst;
int child_inst;
int inst_ahead;

pthread_mutex_t inst_count_lock;
}

I have declared this and allocated the shared memory in my main
program .

In main.c
int main(int argc, char ** argv) {

pthread_mutexattr_t autex_attr;

shmget .....
sync_core = shmat .....
//You can assume that the shared memory initialization is corect
//and the pointer to the shared memory is sync_core.

pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&sync_core->inst_count_lock, &mutex_attr);

sync_core->parent_isnt = 0;
sync_core->child_isnt = 0;
sync_core->inst_ahead = 0;

pid_t pid = fork();

if (pid == 0)
sync_core_fn(pid, child_inst);
else
sync_core_fn(pid, parent_int);

//Please know that child_inst and parent_inst are computed elsewhere.

-----------

sync_core_fn(int core, int inst_count) {

if (core == 0) // child process {

pthread_mutex_lock(&sync_core->child_inst_lock);
sync_core->child_inst = inst_count;
pthread_mutex_unlock(&sync_core->child_inst_lock);
} else { //parent process

sync_core ->parent_inst = inst_count;
pthread_mutex_lock(&sync_core->child_inst_lock);
sync_core->inst_ahead = sync_core->child_inst - sync_core-
>parent_inst;
pthread_mutex_unlock(&sync_core->child_inst_lock);

}


sync_core->child_inst gets garbage values.

Thank you all for your time and help.

Sincerely,
Vandana.
From: Vandana on
Sorry, there is a mistake in the variables used

struct sync_core_shared {
> int parent_inst;
> int child_inst;
> int inst_ahead;
>
> pthread_mutex_t inst_count_lock;
}

should be:
struct sync_core_shared {
int parent_inst;
int child_inst;
int inst_ahead;

pthread_mutex_t child_inst_lock;
}

so initialization changes to
pthread_mutex_init(&sync_core->child_inst_lock, &mutex_attr);

thanks,
v


On Mar 8, 10:45 am, Vandana <nair...(a)gmail.com> wrote:
> Hello All,
>
>    First of all,I am very thankful to all the members who helped me
> with my previous post on the same subject.
>
> I have a shared memory (in the form of the struct shown below )between
> 2 process, and a member of the struct (child_inst) is being updated by
> both the parent & child process. I use a mutex whenever a process is
> modifying it. This modification happens several times when my program
> is being run.
>
> But, when I print this value out, I see that sometimes, it prints out
> garbage values. Is this because sometimes, the mutex is not being
> acquired by the modifying process? If this is the case, can you please
> tell me a better way to do it or if it is better to use spinlocks?
>
> I have the following shared memory struct in the header
>
> struct sync_core_shared {
>  int parent_inst;
> int child_inst;
> int inst_ahead;
>
> pthread_mutex_t inst_count_lock;
>
> }
>
> I have declared this and allocated the shared memory in my main
> program .
>
> In main.c
> int main(int argc, char ** argv) {
>
> pthread_mutexattr_t  autex_attr;
>
> shmget .....
> sync_core = shmat .....
> //You can assume that the shared memory initialization is corect
> //and the pointer to the shared memory is sync_core.
>
> pthread_mutexattr_init(&mutex_attr);
> pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
> pthread_mutex_init(&sync_core->inst_count_lock, &mutex_attr);
>
> sync_core->parent_isnt = 0;
> sync_core->child_isnt = 0;
> sync_core->inst_ahead  = 0;
>
> pid_t pid = fork();
>
> if (pid == 0)
>    sync_core_fn(pid, child_inst);
> else
>    sync_core_fn(pid, parent_int);
>
> //Please know that child_inst and parent_inst are computed elsewhere.
>
> -----------
>
> sync_core_fn(int core, int inst_count) {
>
>     if (core == 0)  // child process {
>
>        pthread_mutex_lock(&sync_core->child_inst_lock);
>        sync_core->child_inst = inst_count;
>        pthread_mutex_unlock(&sync_core->child_inst_lock);
>
> } else { //parent process
>
>     sync_core ->parent_inst = inst_count;
>      pthread_mutex_lock(&sync_core->child_inst_lock);
>      sync_core->inst_ahead =    sync_core->child_inst - sync_core->parent_inst;
>
>        pthread_mutex_unlock(&sync_core->child_inst_lock);
>
> }
>
> sync_core->child_inst gets garbage values.
>
> Thank you all for your time and help.
>
> Sincerely,
> Vandana.

From: David Schwartz on
On Mar 8, 10:45 am, Vandana <nair...(a)gmail.com> wrote:

> sync_core->child_inst gets garbage values.

It almost definitely has nothing to do with your mutexes and
everything to do with a bug somewhere else in your code.

DS
From: Vandana on
Hi,

You were right, it had nothing to do with the mutexes, using spinlocks
also gave me the same behavior.

I have solved it now - but I had to do 2 things:
1. I declared all the members of the struct as volatile.
2. I was redirecting all my debug (fprintf) statements to 2 separate
files (one for each process) through stderr, that was causing some
problem. Now I redirect to the shell then redirect stderr to a file
(using the > operator )

I dont see the problem now, but I am unable to understand fully how my
solutions worked. I can understand the effect volatile would have had,
but how the output redirection affected the process Im still unable to
understand.

Any thoughts?

Thanks,
Vandana.



On Mar 8, 12:16 pm, David Schwartz <dav...(a)webmaster.com> wrote:
> On Mar 8, 10:45 am, Vandana <nair...(a)gmail.com> wrote:
>
> > sync_core->child_inst gets garbage values.
>
> It almost definitely has nothing to do with your mutexes and
> everything to do with a bug somewhere else in your code.
>
> DS

From: David Schwartz on
On Mar 10, 12:04 am, Vandana <nair...(a)gmail.com> wrote:

> I have solved it now - but I had to do 2 things:
> 1. I declared all the members of the struct as volatile.

Immediately remove 'volatile' and find the actual problem. The
'volatile' keyword doesn't actually fix the underlying problem. At
best, it may hide it for a bit.

> 2. I was redirecting all my debug (fprintf) statements to 2 separate
> files (one for each process) through stderr, that was causing some
> problem. Now I redirect to the shell then redirect stderr to a file
> (using the > operator )
>
> I dont see the problem now, but I am unable to understand fully how my
> solutions worked. I can understand the effect volatile would have had,
> but how the output redirection affected the process Im still unable to
> understand.
>
> Any thoughts?

Keep debugging until you find/fix the problem.

The fact that 'volatile' helped suggests that you have a case where
one thread is reading a value while another thread is or might be
modifying it. This is illegal even if they are marked 'volatile', but
it is more likely to work as you intended most of the time.

DS