160 likes | 291 Views
CS241 Systems Programming. Discussion Section Week 2 Nat Thompson. Agenda. Mp0 quiz Review mp0 Fork,exec,etc. Open discussion time. Outline. fork exec Wait kill Coding practices. Program vs Process. Program .h/.c -> .o -> executable Plan to complete a task Process
E N D
CS241 Systems Programming Discussion Section Week 2 Nat Thompson
Agenda • Mp0 quiz • Review mp0 • Fork,exec,etc. • Open discussion time
Outline • fork • exec • Wait • kill • Coding practices
Program vs Process • Program • .h/.c -> .o -> executable • Plan to complete a task • Process • Instance of a program (ie currently executing) • Has alterable state, variables, memory
Process Creation • Running a process from the shell • ls • uptime • Double clicking an icon • Creating a new process in C • fork()
fork • To create a new process within C: • pid_t fork() • http://www.penguin-soft.com/penguin/man/2/fork.html • A new process is created • exactly the same as parent process • except process id and parent id
fork example #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char** argv) { pid_t child_pid = -1; child_pid = fork(); if (child_pid < 0) { printf(”it’s an error!!\n”); } else if (child_pid == 0) { printf(”I’m the child process!!\n”); } else { printf(”child process %d created\n”, child_pid); } return 0; }
exec • fork() creates a new process, but it is still running same program • to load a new program into a process we use exec() • int execve(const char * filename , char *const argv [], char *const envp []); • existing process is overwritten with specified binary • http://www.penguin-soft.com:80/penguin/man/2/execve.html
exec variations • execl, execlp, execle, execv, execvp, execve • “l” : list of arguments • “v” : vector of arguments (think array) • “p” : file pointer to binary • “e” : environment specified
exec example #include <unistd.h> int main(int argc, char** argv) { char *progname = get_prog_name(argc, argv); char **progargs = get_prog_args(argc, argv); ... child_pid = fork(); if (child_pid < 0) { printf(“it’s an error!!\n”); } else if (child_pid == 0) { if (execv(progname, progargs) < 0) { printf(”failed to execute %s!\n”, progname); perror(”child exec:”); return -1; } } ... return 0; }
wait • parent process needs to wait for child process to finish • can wait for a specific process to finish using waitpid() function • pid_t waitpid(pid_t pid , int * status , int options); • blocks until pid is done executing • copies specified process’s return value into status • http://www.penguin-soft.com/penguin/man/2/wait.html
wait example #include <sys/types.h> #include <sys/wait.h> int main(int argc, char** argv) { int result = 0; ... child_pid = fork(); if (child_pid == 0) { printf(”I’m the child process!!\n”); return 100; } else { if (waitpid(child_pid, &result, 0) == -1) { perror(”wait failed:”); return -1; } printf(”child %d returned %d\n”, child_pid, result); } return 0; }
wait gotcha • parent process might receive signals that interrupt wait • causes wait to return even though child not finished! • need to check wait return value: while((waitpid(childpid, NULL, 0) == -1) && (errno = EINTR))
Killing Children (Processes) • A child process can be terminated using the kill command • Really kill just sends a signal to the process • int kill(pid_t pid , int sig ); if (kill(child_pid, SIGTERM) == 0) { /* successfully sent signal */ } • More on signal handling later
Coding practice • C-compiler will let you get away with a lot • heed warnings - leads to safer code • are casts valid? Is that what you meant? - if so do it explicitly! • Make sure to include necessary .h files • Always set default values for variables • Always check return values from functions
Debugging • printf is great, but it’s a pain to remove all printfs when debugging done • use the preprocessor! #ifdef DEBUG printf(”My Debug Statement\n”); #endif • enable with gcc -DDEBUG • block comments: #if 0 ... #endif