This question already has answers here:
How to share memory between processes created by fork()?
(3 answers)
Closed 8 years ago.
I am a beginner on C program, and got a question between worker process.
I write a program which fork a child process, inside the process, it create 2 threads to run and get some values from DB; however, if I fork 2 process, it will create 4 threads totally
I wonder the "extern variables" will be share within this 2 processes? Or independent?
If the variables are not shared, how could I maintenance the consistency between the processes?
(Sorry for my poor english)
Thanks all!!
When you fork a process , both parent and child have their own separate address space and cannot communicate via variables.
When you launch two threads (thread is a lightweight process) inside a process they share the address space of the process and can communicate via variables.
So the "extern variables " will be duplicated twice in your case and you cannot use them to communicate between the processes. To synchronize the two processes you need to use an IPC (inter process communicatin) mechanism such as (for example) a Shared memory for the storage coupled probably to a semaphore to prevent concurrent access.
Related
I'm using C and Winsock2 for my learning project.
I have some questions that I hope some one can confirm.
Let say I have 2 unrelated processes, process A and process B ( without using CreateProcess ). By unrelated I mean it's not parent and child.
1)
Is it possible in Windows to Accept a socket in process A and pass it to process B if they are unrelated?
2)
I guess i have to use WSADuplicateSocket? but that only works for related processes?
I hope someone can explain and confirm the above..
Is it possible in Windows to Accept a socket in process A and pass it to process B if they are unrelated?
Yes, via WSADuplicateSocket():
The WSADuplicateSocket function is used to enable socket sharing between processes. A source process calls WSADuplicateSocket to obtain a special WSAPROTOCOL_INFO structure. It uses some interprocess communications (IPC) mechanism to pass the contents of this structure to a target process, which in turn uses it in a call to WSASocket to obtain a descriptor for the duplicated socket. The special WSAPROTOCOL_INFO structure can only be used once by the target process.
I guess i have to use WSADuplicateSocket?
Yes.
but that only works for related processes?
No. It will work fine between any 2 processes, as long as process A knows process B's Process ID, as that is a required parameter of WSADuplicateSocket().
Can you use a pipe to share threads between two processes in C? I am writing my own shell and want to know if this implementation would be more optimal, if it is even possible?
Each thread is specific to a process and share memory of the calling thread.
If you want efficient inter process communication, you can use shared memory.
See http://man7.org/linux/man-pages/man7/shm_overview.7.html
So I have an application which uses threads. Now when the program first starts up, I want it to go through setting up database connections and whatnot before it backgrounds itself so that whatever/whoever starts the program can know if there was an error starting up.
I did some looking around and have found some resources that say 'do not mix fork and threads', while others say that forking in linux will only duplicate the main thread and leave the others alone.
In the case of the latter (where it just duplicates the main thread), how then do the threads access file level (global) variables? Will the threads not be able to access the variables that are now in the forked process's address space?
Ultimately the goal is to have the application background itself after threads have been created. If this is not possible, I can put the fork before the thread creation, just would like to do it as late as possible.
Note: at the time of the fork, the threads will be doing a sleep() loop until the main thread puts data into a shared variable for them to process. So if the sleep gets interrupted, they wont be harmed.
There is no way to duplicate threads as part of the fork, and the parent's threads will all terminate when the parent exits, so even if they could access the child's memory, it wouldn't help you. You need to either create your threads after forking, or use pthread_atfork to register handlers that will recreate them in the child process. I would recommend just waiting until after forking to create your threads since it's a lot simpler and more efficient.
Why is it that you want to delay forking as long as possible? If you want to maintain connection to a terminal or something until initialization is finished, you can just have the parent process wait to terminate until the child process (with its threads) is done initializing and ready to be "in the background". Various synchronization tools could be used to accomplish this. One simple one would be opening a pipe through which the child sends its output back to the parent to display; the parent could simply exit when it receives EOF on this pipe.
Forking a process creates two different processes and threads in one process will not be able to access memory in the second process. If you want different processes to access the same memory, you want something called shared memory.
When a thread in a process calls fork(), a new process is created by copying, among other things, (1) the full address space of the process and (2) the (one) thread that called fork. If there are other threads in the process, they don't get copied. This will almost certainly lead to bugs in your program. Hence the advice not to mix threads and forks.
If you want to create a background process with many threads, you must fork it before spawning any other thread. Then, the two processes behave normally, like any two isolated processes: threads within one process share the same memory, but your background threads and your foreground process won't share any memory (by default).
I have a main() function and prior to declaring main(), I declare global variables.
Then inside main() 2 processes start: 1 child and 1 parent via fork(). Why can't the parent and child processes share the global variables I declared? What is a good way to handle this? Thank you.
When you fork() you're spawning a new process. Everything at the time of the fork is copied, but after that ... nothing is shared.
You have two choices at that point:
Keep a pipe open between your two processes and communicate changes
Re-write your code to be multi-threaded, where you can access the same data (using locks)
With fork() you create a new process with separate memory space. To communicate between processes you can use signals (using kill())
If you want to share variables, consider using threads (e.g. pthread.h). Then you can use events or mutexes for thread synchronization.
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).