I'm writing an application with Producer who makes and sends messages and Consumer who is getting the messages. I have to set environment variable in producer app and read it in consumer app.
In producer app I did this command
putenv("MSG_KEY=15");
And in the consumer app i tried to get the variable like this
char *z=getenv("MSG_KEY");
But it doesn't return any value (I get nil value). If I write the same command in producer it works if I use putenv() few lines before. I think the problem is that it sets variable only locally so I cannot access it from another program but I don't know how to solve it.
Don't know if it matters but I'm using Linux system.
Environment variables are private to a process. You cannot set them in one process and expect to read them in another process.
The only time you can communicate anything via environment variables to another process is from a parent process to a child, and only at the time that the parent spawns the child. The parent may copy, modify, add, or remove environment variables when it spawns the child. From then on they become entirely separated. Change that one process makes to the variables, is not visible to the other.
Related
My app is suppose to run long term (usually idling). If I try to open a second app (or trigger the app via global hotkey) I'd like my existing instance to receive some kind of IPC message and bring itself to the front. How do I do this on linux? The problem I've been running into is if I hold a global lock it doesn't automatically free when the instance close (usually I unlock it but an app can crash). If I try to use mkfifo I have no idea if I'm the first instance or not and every solution I can think of seems to require a lot of code and usually that's a sign to me I might be doing something wrong
There are many IPC primitives, all possible to use.
A simple one is using a named pipe: If the pipe doesn't exist then the program creates it and starts as usual. Then it polls the pipe at regular intervals to see if something can be received on the pipe, in which case the program receives it (and discards it) and puts itself to the "front".
If, on the other hand, the named pipe exists, then the program sends a simple dummy message through it, and exits.
I would use a flag file, e.g. /run/service-name/pid with PID of the first running instance. A new instance would check this file, if it does not exists, create it, if it does, send a SIGUSR1 to the PID in the file.
#Some programmer dude's answer above provides a bit more of flexibility.
I am trying to understand the specifications of a C coding project using fork() and execv().
Essentially, I am told I need to either propagate or not propagate the environment variables of the shell to the command I am executing in a child process depending on a binary value.
Though, regardless, I am supposed to pass in any additional environmental variables I am provided to the command I am executing in the child.
This whole idea is new information to me, so I am just trying to understand what exactly this means.
To my understanding, when a child is created using fork(), the environmental variables of the parent process are passed on to the child, and then any additional environmental variable changes can be made as an argument of the execve() function when it is run within the child.
But if this is the case, then the environmental variables are always propagated from the parent/shell anyway right? So what is the difference and how would I not propagate those variables?
Thanks for your time.
You're still in control after the fork() and before the execv().
You can make changes to your child's environment that you don't want to make to your parent -- including calls to unsetenv() -- in that process.
Alternately, you can construct a new environment entirely and pass it in the envp argument to execve().
If you understood fork(2) then you'll know that the parent and the child are exactly the same (except for the value returned by fork()), so the environment of the parent process is exactly the same as the environment of the child. there's no other way to pass environment to a child process... because execve(2) doesn't create a new process. You only load the process' virtual space by loading a new program on it. And this allows you to change the environment, as it happens with the argument list. Think of argc and argv as some way of passing positional parameters to a program, and the environment as some way to pass named parameters to a program. Both are exactly the same kind of things, but ones are seek by position, while the others are accessed by name.
But no new process is created on execve(2) (nor in any of its variants)
OS: Windows Language: C/C++
The design demands to use a mutex variable across process and its sub processes.
If I create mutex in one process, I have to open the mutex in another processs to check the critical section's availablity.
To open the mutex, I need to know the name of the mutex created in parent process. Suppose, If I keep the mutex as my application name. I could know the name of the mutex, as it is fixed. However, If I load the second instance of my application parallel, there would be a confusion.
Can the following be the better idea?
I have an idea to name the mutex in the parent process as the process id. So now I need to fetch the Parent's process ID from the child process/grand child process to open the mutex.
I guess there are no direct ways to fetch parent process id from the grand child process. So I have to pass on the process id in every create process api(in lpenvironment parm).
Can anyone suggest a simple method, as mutexes are most commonly used.... I am a newbie.
The main idea is fine, but you can maybe make some implementation tweaks.
For one, if your application involves multiple processes cooperating, then the main "controller" process which spawns sub-processes can easily pass its PID via a command line argument. If sub-processes spawn their own children as well, they can transfer the PID via the same mechanism.
Taking this idea further, you can also skip the PID entirely and pass the mutex name itself via command line argument to child processes. This approach has the advantage that the parent and child processes do not need to both include code that derives the mutex name from the PID. By passing the mutex name itself you decouple child processes from having to know how it is produced. This approach is used by many mainstream apps, e.g. Google Chrome.
And finally, you can maybe do better by adding a random string (a GUID maybe?) to the mutex name. I don't believe anyone will name their own global synchronization object with the same name, but some extra precautions won't hurt.
As I understand it, you propose to use a process ID (PID) as the basis for naming a mutex to be used by your application and its subprocesses. This way, they will have their own mutex name that will not clash with the mutex name used by a second instance of your application.
This appears valid, but handles would be reliable than PIDs, because PIDs can get recycled. The method of using handles (passing them to child processes, similar to what you sugggest) is discussed on this StackOverflow thread.
I think passing the information you need to share to child processes is the way to go. Windows has the concepts for progress groups for a console process and its child processes, but this is really designed for being able to signal all the processes as a group -- not for sharing information among the group.
And there are also job objects for managing a group of processes that belong to a common job, but again, this is designed for managing a group of processes, not for information sharing between the processes in the group.
If I interprete the wording "a process and its sub-processes" as well as "child/grandchild", the situation is that you have a single parent process that launches one or several children (or, children launching grandchildren). Or, any combination of these, but either way, every process we talk about using the same mutex that is created by the parent.
If that assumption is correct, why not just use something embarrassingly simple as:
#define MUTEXNAME "MzdhYTYzYzc3Mzk4ZDk1NDQ3MzI2MmUxYTAwNTdjMWU2MzJlZGE3Nw"
In case you wonder where this one came from, I generated it with this one-liner:
php -r "echo substr(base64_encode(sha1('some text')), 0, -2);"
Replace 'some text' with your name, the current date, or whatever random words are at your mind at this very moment. The chances that any other application on your system will ever have the same mutex name is practically zero.
my question is somewhat conceptual, how is parent process' data shared with child process created by a fork() call or with a thread created by pthread_create()
for example, are global variables directly passed into child process and if so, does modification on that variable made by child process effect value of it in parent process?
i appreciate partial and complete answers in advance, if i'm missing any existing resource, i'm sorry, i've done some search on google but couldn't find good results
thanks again for your time and answers
The semantics of fork() and pthread_create() are a little different.
fork() will create a new process, where the global variables will be separate between the parent and children. Most OS implementations will use copy-on-write semantics, meaning that both the parent and child process will use the same physical memory pages for all global variables until one of the processes attempts to edit the physical memory, at which point a copy of that page is made, so that now each process gets its own copy and does not see the other process's, so that the processes are isolated.
pthread_create() on the other hand, creates a new thread within the same process. The new thread will have a separate stack space from the other running threads of the same process, however the global variables and heap space are shared between all threads of the same process. This is why you often need a mutex to coordinate access to a shared piece of memory between multiple threads of the same process.
TL;DR version: with fork(), you don't see the other guy's changes; with pthread_create() you do.
A fork creates an almost exact copy of the calling process, including memory and file descriptors. Global variables are copied along with everything else, but they are not in any way linked to the parent process. Since file descriptors are also copied, parent and child can interact via these (as long as they're setup properly, usually via pipe or socketpair).
There's a big difference between processes created by fork and between threads created with pthread_create. Processes don't share global variables and should communicate through pipes, sockets, or other tools provided by the OS. A good solution is MPI - which is a message-passing library for inter-process communication.
Threads are quite different. A thread created with pthread_create shares all the global variables with its caller. Moreover, the caller can pass an arbitrary structure into the thread, and this structure will also be shared. This means that one should be extremely careful when programming with threads - such amounts of sharing are dangerous and error prone. The pthread API provides mutexes and conditions for robust synchronization between threads (although it still requires practice and expertise to implement correctly).
I have my own POSIX application which starts a child process. I want the parent process to be notified with the names of all files the child process reads or writes, as well as the file names of any child processes the child spawns, and any dynamic libraries it loads. Similarly, I need to monitor all child processes spawned by child processes, etc.
How is this done?
I have two ideas for this.
Method 1 - The "real way".
I think you want ptrace. But it isn't going to be easy to use.
Essentially this call is for writing a debugger. Note that PTRACE_SYSCALL steps until the next syscall. At which point you might be able to use more ptrace calls to peek at the process's memory to observe if it's, say, a call to open().
Method 2 - The lazy, hackish way.
You could use the LD_PRELOAD environment variable. That is, write a shared library with your own implementation of the calls you want to hook (say, open(), dlopen()), adding your own code and dispatching to the normal libc version. Then you point the LD_PRELOAD environment variable at this shared library so the dynamic linker will load it at process start.
One downside to this approach is that if a process knows it's being observed this way, it can reset the environment variable and execute itself again, and evade detection. Another I can think of is that as a security feature this environment variable is not honored if you're root.