Operations on Processes
Notes
- This is section 3.3
- Plus we will do some linux programming.
- The family of a process
- On linux
- All real processes are started by systemd
- All kernel threads are started by kthreadd
- The kernel starts each of these during the boot up process.
- Anything in [] is a kernel thread
- These are just manifestations of the kernel
- They seem to have been added to allow for true parallelism
- ps -efH shows the process tree
- We can see that systemd has pid of 0
- Then find the first sshd
- Then find the sshd-session
- Then my bash
- Then my ps
- In each case, the parent program started the child program with the
forkcall.
- On linux
- Some linux system programming
-
pid_t getpid(void)- needs
#include <unistd.h>, but that is frequently there. - also
pid_t getppid(void) - This is a system call.
- When we do this, we jump to the kernel
- And we have the chance to be swapped out.
- But we need to go to kernel mode as the memory where the process PID is stored is not ours, it is the kernel's
- needs
- The
/procfile system- Is a virtual file syste, we will discuss this later
- Provides access to the kernel data structures
- In this case, we are interested in /proc/id
- where id is the process id
- or
/proc/self -
/proc/self/commis the command -
/proc/self/statusis the status
- Some Code
-
#include <iostream> #include <unistd.h> #include <fstream> using namespace std; void ReportAboutMe(); int main() { ReportAboutMe(); return 0; } string GetComm(pid_t pid) { string commFileName{"/proc/"+to_string(pid)+"/comm"}; ifstream commFile{commFileName}; string comm; getline(commFile, comm); commFile.close(); return comm; } void ReportAboutMe() { pid_t myPid{getpid()}; pid_t myParent{getppid() }; cout << "Process id: " << myPid << endl; cout << "My name: " << GetComm(myPid) << endl; cout << "Parent process id: " << myParent << endl; cout << "Parent name: " << GetComm(myParent) << endl; cout << endl; return; }
-
-
pid_t fork(void);- needs
#include <unistd.h>, but that is frequently there. - Takes no arguements
- Returns
- In the parent process, the id of the newly created child
- In the child process, 0
- The parent and child processes are nearly identical
- Including
- Memory
- Open Files
- Program Counter, Register Values, ...
- The child actually gets a copy of the parent memory
- IE take PCB and duplicate it, change a few fields
- Duplicate memory and other resources
- excluding
- return value
- Some settings.
- But they would do the same thing if we didn't do anything different in the program.
- Code
- Change main to be
-
int main() { ReportAboutMe(); cout << "About to fork " << endl; pid_t child{fork()}; ReportAboutMe(); return 0; } - Why does it print twice after it forks?
- WARNING: Fork Bomb
- Don't write one.
- If you do, let someone know instantly.
- Or run it on a lab/personal machine you can reboot.
- needs
-
pid_t wait(int *_nullable wstatus)- Needs
#include <sys/wait.h> - waits for a child process to exit
- Returns the id of the process that exited.
- If we want, we can gett more information via wstatus
- Was the child terminated, stopped, or did it call exit?
- If it called exit, what was the value returned?
- If it was terminated, what was the signal that killed it?
- There are other versions of this (waitpid, waitid)
- Needs
- Code
- Add
#include <sys/wait.h> - Change main to be
-
int main() { ReportAboutMe(); cout << "About to fork " << endl; pid_t child{fork()}; if (child == 0) { cout << "A report from the child " << endl; ReportAboutMe(); return 0; } pid_t exitProcessID{wait(nullptr)}; cout << "Parent, child process id is " << child << endl; cout << "A report from the parent now that " << exitProcessID << " has exited" << endl; ReportAboutMe(); return 0; }
- Add
-
- This is implemented in forker.cpp.