Working with Unix Processes¶
The book uses ruby to explore UNIX processes. Jesse also gives the corresponding man page the command maps to.
PID¶
- On any UNIX system. Just type man <command_name>
- Each process has a PID:
puts Process.pid
- maps to getpid(2)
- A global (albeit implicit) way to retreive the current pid is using $$
File Descriptor¶
- In UNIX everything is treated as a file(resource). Any time a resource is opened within a process it is assigned a file descriptor number.
- File descriptor are NOT shared between unrelated processes. They live and die with the process they are bound to:
passwd = File.open('/etc/passwd')
puts passwd.fileno => 3
- In ruby, open resources are represented by IO class
- The fileno is the way kernel keeps track of the resource:
passwd = File.open('/etc/passwd')
puts passwd.fileno => 3
hosts = File.open('/etc/hosts')
puts hosts.fileno => 4
passwd.close
null = File.open('/dev/null')
puts null.fileno => 3
- Key points from the above example
- File descriptors take the lowest unused value.
- Once a descriptor is closed, the number becomes available again.
- What happened to 0,1 and 2 file descriptors?
puts STDIN.fileno => 0
puts STDOUT.fileno => 1
puts STDERR.fileno => 2
- Ruby IO maps to open(2), close(2), read(2), write(2),
- pipe(2), fsync(2), stat(2) etc
Resource Limit¶
- Limits are imposed by the kernel:
Process.getrlimit(:NOFILE) => [2560, big_number]
- getrlimit return a 2-element array
- First number is the soft limit
- Second number is hard limit
- The soft limit can be bumped by:
Process.setrlimit(:NOFILE, 4096)
To set soft limit to the hard limit:
Process.setrlimit(:NOFILE, Process.getrlimit(:NOFILE)[1])
- If you exceed the soft limit, an exception will be raised (Errno::EMFILE)
- Real world examples:
- If you want to handle thousands of sumultaneous network connections
- Restrain system resources when executing third part code
- Maps to getrlimit(2) and setrlimit(2)
Environment of the Process¶
- A little ruby heavy chapter
- Every process inherits environment variable from its parent. Its set per process and global to each process.
- Ruby ENV used hash-style accessor, but doesn’t implement all the Hash API:
puts ENV['EDITOR']
puts ENV.has_key?('PATH')
- Access to special Array called ARGV
- You can change the name of the process:
puts $PROGRAM_NAME
10.downto(1) do |num|
$PROGRAM_NAME = "Process: #{num}"
puts $PROGRAM_NAME
end
- Somewhat maps to setenv(2) and getenv(2). Also, environ(2)