Shared memory in C with LinkedList - c

I have to develop a mini-shell in C. In this project we have to deal with local variables and environment variables. So we can have two process that shared environment variables, a variable create in the child can be seen in the father and inversely.
My teacher says:
The environment variables are stored in a shared memory area that is created by the first copy of your shell that runs and is initialized with all the variables defined in the envp array. The last copy of your shell that runs at any given time must destroy that space. This shared memory area is to be managed as a memory by subdivision. The shared memory area is a concurrent access memory area with multiple possible simultaneous reads but only 1 write possible at a given time. Implementation must give priority to writing.
So we need shared memory with linked list who contains:
the name of variable (char*)
the int return by shmget()
and a char* return by shmat(), the value of variable
But when we create a environment variable in the father there is not in the child.
So I think this method is not correct, how can we represents this problem ?
Maybe not use a linked list ?
Thank you.
TF.

I understand !
My teacher say me to create a shared memory space with fixed size ! It's simple now.
Thank you everyone.

Related

How to store nodes of a list into shared memory

I am trying to make many clients communicate with each other via many terminals.I have forks inside my program and I create pipes so the clients can read/write from/to other clients.Because I create many processes I need shared memory to store some infos and in particular i want to store nodes that are created from each kid.How can I do this?
This is my struct:
typedef struct client{
char *numofclient;
struct client *nextclient;
}client;
Before forking anything create a shared memory area using mmap. Read the man page and use the shared flags. If on Windows it's different so look up VirtualAlloc and of course you can't fork.
You'll need a memory allocator for your shared memory. That can be super easy: just increment a char pointer for an allocation and never free anything. Or it can be as complex as you want. You may be able to find a library online.
If you need a mutex create one in the shared memory area and be sure to use the flags for a shared mutex.
Since you are forking you can use pointers because the shared memory will remain mapped in place in each process copy. Otherwise you'd need to use offsets from the map start.
I think you can make the systemV shared memory using shmget, read man pages.
You can decide an upper limit of how many Process are going to be created and provide that much size accordingly to shmget.
So, whenever you child process wants to store list it can just attach to the shared memory and append its data in shared memory.

Accessing static functions/variable from different threads

I use a third side library written in C. It is designed to run as singleton and contains plenty of static functions, variables and user interface. I need to be able to run it with multiple instances so they do not interfere with each other. For example if one threads sets static variable
static int index = 0;
index = 10;
the second thread still sees index = 0.
I am not sure if it is even possible to implement.
What you are asking is not possible.
Let's assume for pedagogical purposes that you are on a unix machine.
Any process (such as the executable ./a.out) has the following Memory layout :
Text
Data
Initialized
Uninitialized
Heap
Stack
When you create a thread, then it shares all these memory segments except the Stack section(basically each thread gets a new stack pointer).
Moreover the static variables are stored in the Data segment (in your case Initialized data segment) which is a shared memory segment, hence when one thread changes it, it changes for all other threads as well.
So threads only have the following things local to themself
Stack pointer
Program Counter
registers
Image source : llnl.gov
Hope it helped :-).

Shared memory addresses

I am using C on Linux, and allocating 2 shared memory segments.
The first segment is created in a main program, then I call a subprocess and create the second segment.
In the subprocess, I place the address of the second segment in a pointer I set aside in the first segment.
Upon returning to the main program, when I attach to the second segment and compare the pointers (the one returned from shmat, and the one previously stored by the subprocess) I find they are different.
Is this expected?
Thanks, Mark.
Yes, this is expected. Mapping to a common address in the virtual space of the two processes would be a very constraining limitation. Among others, the memory manager would have to know simultaneously which processes are willing to map, so that it finds a common free area. This would defeat the very principle of virtual memory (every process sees a blank address space), and cause configurations impossible to arbitrate.
Sharing at common addresses is indeed possible, but only makes sense when the mapping is to some reserved section of the address space, so that it doesn't get mapped elsehow.

How to read the variable value from RAM?

I've written a program using dynamic memory allocation. I do not use the free function to free the memory, still at the address, the variable's value is present there.
Now I want to reuse this value and I want to see all the variables' values that are present in RAM from another process.
Is it possible?
#include<stdio.h>
#include<stdlib.h>
void main(){
int *fptr;
fptr=(int *)malloc(sizeof(int));
*fptr=4;
printf("%d\t%u",*fptr,fptr);
while(1){
//this is become infinite loop
}
}
and i want to another program to read the value of a because it is still in memory because main function is infinite. how can do this?
This question shows misconceptions on at least two topics.
The first is virtual address spaces and memory protection, as already addressed by RobertL in his answer. On a modern operating system, you just can't access memory belonging to another process (even if you knew the physical address, which you don't because all user space processes work on addresses in their private virtual address space). The result of trying to access something not mapped into your address space will be a segmentation fault. Read more on Wikipedia.
The second is the scope of the C standard. It doesn't know about processes. C is defined in terms of an abstract machine executing your program (and only this program). Scopes and lifetimes of variables are defined and the respective maximum is the global scope and a static storage duration. So yes, your variable will continue to live as long as your program runs, but it's scope will be this program.
When you understand that, you see: even on a platform using a single global address space and no memory protection at all, you could never access the variable of another program in terms of the C standard. You could probably pass a pointer value somehow to your other program and use that, maybe it would work, but it would be undefined behavior.
That's why operating systems provide means for inter process communication like shared memory (which comes close to what you seem to want) and pipes.
When you return from main(), the process frees all acquired resources, so you can't. Have a look on this.
First of all, when you close your process the memory you allocated with it will be freed entirely. You can circumvent this by having 1 process of you write to a file (like a .dat file) and the other read from it. There are other ways, too.
But generally speaking in normal cases, when your process terminates the existing memory will be freed.
If you try accessing memory from another process from within your process, you will most likely get a segmentation fault, as most operating systems protect processes from messing with each other's memory.
It depends on the operating system. Most modern multi-tasking operating systems protect processes from each other. Hardware is setup to disallow processes from seeing other processes memory. On Linux and Unix for example, to communicate between programs in memory you will need to use operating system services for "inter-process" communication, such as shared memory, semaphores, or pipes.

Semaphores for different parts of the same shared memory block in C

I have a question on how to set up a shared memory segment for my program.
In my program I want to have a main structure to contain 50 different accounts.
Something that looks like this.
struct list{
struct account[50];
};
Within each account there is just some basic info
struct account{
int x;
char * y;
};
Now, I want my entire list to be located in a shared memory segment as different child processes of my main process will be updating different accounts in the list.
However, I only want a child process to be able to access a certain account in this list. How exactly would I go about setting up a shared memory segment that can be locked down by a child process in different parts? For example, I want a semaphore that can lock down access to account[32] in the shared memory segment. This means that another process could be updating account[29] in the shared memory segment at the same time with no problem.
I am not really looking for concrete code examples (although those would be helpful), but more of a conceptual understanding of the best way to set up shared memory for this program.
Thanks.
If I understood what this is about, I see two alternatives:
The first one is to modify struct account, so there's one extra field, a semaphore. Any process should P() on the semaphore before it accesses the other account's fields, and V() when it's done with it.
The second would be to modify struct list, adding an extra array of semaphores, same size as the array of accounts, assigning each semaphore in the array with the same-indexed account, and using P() and V() on it again, before and after accessing the corresponding account.

Resources