LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Need help writing and reading shared memory (https://www.linuxquestions.org/questions/linux-newbie-8/need-help-writing-and-reading-shared-memory-418920/)

djgannon 02-23-2006 08:51 PM

Need help writing and reading shared memory
 
Hello,
I'm trying to write 4 programs all reading from shared memory. I can write 1 reader and 1 writer program. The problem is when I try to get my program reading from shared memory to add a number on to the front of the message in my shared memory for a third program to read it. I have added my reader code that I'm using to try to do this. Any help would be appreciated.

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

using namespace std;
#define TEXT_SIZE 2000
struct shared_memory_struct // definition
{
int written_flag; // this flag will be set: to 0 when there
// is nothing new in shared memory to read
char some_text [TEXT_SIZE];
};

int main ( )
{
int running = 1;
int shmid;
struct shared_memory_struct *shared_data; // declaration
void *shared_memory = (void *)0;
// This is just to take an input to continue at end.
char buffer[BUFSIZ];
char *concat2 = buffer;

/* Create a shared memory segment with pre-selected key (param 1).
* The size of the created segment will be the size of the struct
* we have set up to handle the memory (param 2). param 3 indicates
* that owner, group, and world can assess the shared memory (0666)
* and that the shared memory segment should be created if it doesn't
* already exist (IPC_CREAT).
*/
shmid = shmget ((key_t)4321, sizeof(struct shared_memory_struct), 0666 | IPC_CREAT);


/* If the sharedmemory segment is successfully created (or was
* already successfully created by another process) shmget will
* return the id of the segment. It will return -1 if there was
* an error.
*/
if (shmid == -1)
{
cerr << "shmget failed" << endl;
return 1;
}

/* Attach to the shared memory to use it. param 1 is the
* id of the segment returned by shmget. param 2 allows us to specify
* the address at which we want the shared memory to be attached.
* If this is a null pointer (as in this example), the system will
* choose for us where to attach the shared memory. param 3 is a
* set of bitwise flags.
*/
shared_memory = shmat(shmid, (void *)0, 0);

/* If the attach is successful, it will return a pointer to the
* first byte of the shared memory. If unsuccessful, it will
* return -1.
*/
if (shared_memory == (void *)-1)
{
cerr << "shmat failed" << endl;
return 2;
}

cout << "Memory attached at :" << (int)shared_memory
<< endl << " with shmid: " << shmid << endl;

/* Note that the following "maps" our structure to the shared
* memory segment.
*/
shared_data =
(struct shared_memory_struct *)shared_memory;

/* Assume the reader program is started before the writer.
* Set the flag to indicate that we are ready to read.
*/
shared_data->written_flag = 0;

while (running)
{
/* We will stay in the while loop continuously checking
* the flag in shared memory until it is set to 1.
*/
if (shared_data->written_flag)
{
/* Once the flag is set, read the information and
* display.
*/
cout << "You wrote: " <<
shared_data->some_text << endl;
concat2 = ("021804 %s", buffer);
strcpy (shared_data->some_text, concat2);
// Wait a bit so the writer needs to wait
sleep (1);
// Reset the flag so program 3 can read data
shared_data->written_flag = 2;
// If user entered "end" for other process, it's
// time to exit.
if (strncmp (shared_data->some_text,
"end", 3) == 0)
{
running = 0;
}
} // end if
} // end while

// Detach from shared memory.
if (shmdt(shared_memory) == -1)
{
cerr << "shmdt failed" << endl;
return 3;
}

cout << "We have detached from shared memory, but have not deleted it" << endl << "Hit any key, then enter to continue" << endl;
cin >> buffer;

/* This actually removes the shared memory from the system.
* param 1 tels which segment, param 2 is the command to shmctl
* (which can perform several actions) to remove the memory, and
* param 3 is not used (set to 0) when param 2 is set to IPC_RMID.
*/
if (shmctl(shmid, IPC_RMID, 0) == -1)
{
cerr << "shmctl(IPC_RMID) failed" << endl;
return 4;
}
return 0;
}


All times are GMT -5. The time now is 04:02 PM.