LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
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
  Search this Thread
Old 06-27-2011, 11:12 AM   #1
utdrmac
LQ Newbie
 
Registered: Jun 2011
Location: Houston, TX
Distribution: RHEL 5.6
Posts: 9

Rep: Reputation: Disabled
Question copying an array of structs to new variable


Hi all,
I had a question about threads and mutexes recently answered and a members' answer sparked a different problem.

'Nominal Animal' in the post mentioned said I should hold a mutex only long enough to copy my data to a temporary variable and then output by reading that temp. Here's some code on this. I must be copying the array of structs wrong because when the gui thread reads the temp copy, I end up with lots of garbage. Even running through gdb verifies that different data is in the temp array-copy than in the original.

How do I go about copying this array of structs to another variable correctly in the gui thread?

Thanks!!
-Matthew

Code:
typedef struct
{
        char server[40];
        int sbm;
        int position;
        int isSeparator;
        int errno;
        char error[40];
} replInfo_st;

replInfo_st *replInfo;

int windowManager()
{
        // replInfo won't change size after program init so
        // safe use its size to make this temp one
        replInfo_st *tempReplInfo = malloc(sizeof(replInfo));
        
        for(;;)
        {
                // copy to temp
                pthread_rwlock_wrlock(&rwlock);
                memcpy(tempRepInfo, replInfo, sizeof(replInfo));
                pthread_rwlock_unlock(&rwlock);

                // print out using temp variable
                ....
        }
}

int main()
{
        ....
        replInfo = (replInfo_st *) malloc(sizeof(replInfo_st) * numServers);

        /* code to populate all array members of replInfo goes here */

        /* spawn and wait for threads here */
}
 
Old 06-27-2011, 11:52 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
You are only allocating the size of a pointer (4 bytes on 32-bit system, 8 bytes on 64-bit system) with this statement:
Code:
replInfo_st *tempReplInfo = malloc(sizeof(replInfo));
As for what you are attempting, you intent is correct, but you do need to allocate the correct space, and of course, copy the appropriate amount of data from the source.

The statement above should be:
Code:
replInfo_st *tempReplInfo = malloc(sizeof(replInfo_st) * numServers);
and then followed by:
Code:
for (;;)
{
   pthread_rwlock_wrlock(&rwlock);
   memcpy(tempReplInfo, replInfo, sizeof(replInfo_st) * numServers);
   pthread_rwlock_unlock(&rwlock);

   ...
}
I personally do not see the need for you to rely on global variables, when these could just as easily be passed into the function. Nevertheless, if you use the code above, you will need to declare 'numServers' as a global variable.

Last edited by dwhitney67; 06-27-2011 at 11:56 AM.
 
Old 06-27-2011, 12:01 PM   #3
utdrmac
LQ Newbie
 
Registered: Jun 2011
Location: Houston, TX
Distribution: RHEL 5.6
Posts: 9

Original Poster
Rep: Reputation: Disabled
I'll give that a try thanks.

A bit more background... the app reads in hostnames from a flat-file and sets numServers to however many it read. I might have to make that one global now. replInfo is used by all N threads to it has to be global (right?) and the tempRepInfo is local to that thread.

Thanks so much!
 
Old 06-27-2011, 12:27 PM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by utdrmac View Post
I'll give that a try thanks.

A bit more background... the app reads in hostnames from a flat-file and sets numServers to however many it read. I might have to make that one global now. replInfo is used by all N threads to it has to be global (right?) and the tempRepInfo is local to that thread.

Thanks so much!
Global variables are not always necessary. Your thread(s) can accept a locally declared object, as long as that object is not destroyed (or falls out of scope) during the lifetime of the thread(s). Consider the following, which is based on the project from your other thread:

Code:
...

#define NUM_WORK_THRDS 60

typedef struct
{
   int               id;
   int*              array;
   pthread_rwlock_t* rwlock;
} ThreadData;


void* workThread(void* arg)
{
   ThreadData* tdata = (ThreadData*) arg;

   for (;;)
   {
   }

   return NULL;
}

void* readThread(void* arg)
{
   ThreadData* tdata = (ThreadData*) arg;

   for (;;)
   {
   }

   return NULL;
}


int main()
{
   int              array[NUM_WORK_THRDS];
   ThreadData       tdata[NUM_WORK_THRDS];
   pthread_rwlock_t rwlock;
   pthread_t        tid[NUM_WORK_THRDS + 1];   /* +1 for reader thread */

   pthread_rwlock_init(&rwlock, NULL);

   for (int i = 0; i < NUM_WORK_THRDS; ++i)
   {
      tdata[i].id     = i;
      tdata[i].array  = array;
      tdata[i].rwlock = &rwlock;

      pthread_create(&tid[i], NULL, workThread, &tdata[i]);
   }

   pthread_create(&tid[i], NULL, readThread, &tdata[0]);

   /* ... make sure this thread (main thread) does not exit; or better yet
          dispense with the readThread above, and do that task here.
    */

   return 0;
}

Last edited by dwhitney67; 06-27-2011 at 12:28 PM.
 
Old 06-27-2011, 12:47 PM   #5
utdrmac
LQ Newbie
 
Registered: Jun 2011
Location: Houston, TX
Distribution: RHEL 5.6
Posts: 9

Original Poster
Rep: Reputation: Disabled
Oh I see; because you put a pointer var in the struct, you just assign the address of the initialized mutex. Everybody is still operating on the same mutex. Neato.

I also had the #define for the number of threads in the beginning versions of my app, but I wanted that number to be variable so you didn't have to recompile the program if you brought a new sever online.

And I'll take a look at moving the "gui" thread to inside the main to reduce the number of threads by 1.

Thanks!
 
Old 06-27-2011, 12:51 PM   #6
utdrmac
LQ Newbie
 
Registered: Jun 2011
Location: Houston, TX
Distribution: RHEL 5.6
Posts: 9

Original Poster
Rep: Reputation: Disabled
By putting the mutex pointer into the struct, however, you will increase the amount of memory the application uses by (sizeof(pthread_rwlock_t) * numServers) right? Because instead of having 1 global variable, you now have a copy for each thread, right?
 
Old 06-27-2011, 12:55 PM   #7
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by utdrmac View Post
By putting the mutex pointer into the struct, however, you will increase the amount of memory the application uses by (sizeof(pthread_rwlock_t) * numServers) right? Because instead of having 1 global variable, you now have a copy for each thread, right?
Yes that is correct. Running on a 64-bit system, with say 100 servers to support, the total amount of memory for all of those pointers will be 800 bytes.

My suggestion was merely to show that global variables are not always warranted.
 
Old 06-27-2011, 02:16 PM   #8
utdrmac
LQ Newbie
 
Registered: Jun 2011
Location: Houston, TX
Distribution: RHEL 5.6
Posts: 9

Original Poster
Rep: Reputation: Disabled
Haha. Love the emoticon for 800 bytes. Coolio. Everything looks great on my app now! Thanks so much!
 
  


Reply



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



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] shell script help: copying directory list into an array and then accessing the array richman1234 Linux - Newbie 6 07-25-2010 11:19 PM
ARGGGH! Passing array of structs to function in C. CoderMan Programming 5 02-05-2009 10:44 PM
c: iterate an array of structs kpachopoulos Programming 2 08-15-2006 11:06 AM
Array structs - passed to function cdog Programming 4 02-02-2006 03:07 PM
confusing array of structs kpachopoulos Programming 1 11-23-2005 02:13 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:49 AM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration