static const size_t kNumChildren = 5;
static size_t numChildrenDonePlaying = 0;
static void reapChild(int sig) {
exitIf(waitpid(-1, NULL, 0) == -1, kWaitFailed,
stderr, "waitpid failed within reapChild sighandler.\n");
numChildrenDonePlaying++;
sleep(1); // represents time spent doing other useful work
}
int main(int argc, char *argv[]) {
printf("Let my five children play while I take a nap.\n");
exitIf(signal(SIGCHLD, reapChild) == SIG_ERR, kSignalFailed,
stderr, "Failed to install SIGCHLD handler.\n");
for (size_t kid = 1; kid <= 5; kid++) {
pid_t pid = fork();
exitIf(pid == -1, kForkFailed, stderr, "Child #%zu doesn't want to play.\n", kid);
if (pid == 0) {
sleep(3 * kid); // sleep emulates "play" time
printf("Child #%zu tired... returns to dad.\n", kid);
return 0;
}
} while (numChildrenDonePlaying < kNumChildren) {
printf("At least one child still playing, so dad nods off.\n");
snooze(5); // implementation in /usr/class/cs110/local/include/sleep-utils.h
printf("Dad wakes up! ");
}
printf("All children accounted for. Good job, dad!\n");
return 0;
}
myth22> ./five-children
Let my five children play while I take a nap.
At least one child still playing, so dad nods off.
Child #1 tired... returns to dad.
Child #2 tired... returns to dad.
Dad wakes up! At least one child still playing, so dad nods off.
Child #3 tired... returns to dad.
Child #4 tired... returns to dad.
Dad wakes up! At least one child still playing, so dad nods off.
Child #5 tired... returns to dad.
Dad wakes up! All children accounted for. Good job, dad!
myth22>static const size_t kNumChildren = 5;
static size_t numChildrenDonePlaying = 0;
static void reapChild(int sig) {
exitIf(waitpid(-1, NULL, 0) == -1, kWaitFailed,
stderr, "waitpid failed within reapChild sighandler.\n");
numChildrenDonePlaying++;
sleep(1); // represents time that useful work might be done
}
int main(int argc, char *argv[]) {
printf("Let my five children play while I take a nap.\n");
exitIf(signal(SIGCHLD, reapChild) == SIG_ERR, kSignalFailed,
stderr, "Failed to install SIGCHLD handler.\n");
for (size_t kid = 1; kid <= 5; kid++) {
pid_t pid = fork();
exitIf(pid == -1, kForkFailed, stderr, "Child #%zu doesn't want to play.\n", kid);
if (pid == 0) {
sleep(3); // all kids play together for three seconds
printf("Kid #%zu done playing... runs back to dad.\n", kid);
return 0;
}
} while (numChildrenDonePlaying < kNumChildren) {
printf("At least one child still playing, so dad nods off.\n");
snooze(5);
printf("Dad wakes up! ");
}
printf("All children accounted for. Good job, dad!\n");
return 0;
}
myth22> ./indistinguishable-pentuplets
Let my five children play while I take a nap.
At least one child still playing, so dad nods off.
Kid #1 done playing... runs back to dad.
Kid #3 done playing... runs back to dad.
Kid #4 done playing... runs back to dad.
Kid #2 done playing... runs back to dad.
Kid #5 done playing... runs back to dad.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
Dad wakes up! At least one child still playing, so dad nods off.
<ctrl-c>
myth22>static void reapChild(int sig) {
pid_t pid;
while (true) {
pid = waitpid(-1, NULL, WNOHANG);
if (pid <= 0) break;
numChildrenDonePlaying++;
}
exitUnless(pid == 0 || errno == ECHILD, kWaitFailed,
stderr, "waitpid failed within reapChild sighandler.\n");
sleep(1); // represents time that useful work might be done
}
myth22> ./pentuplets
Let my five children play while I take a nap.
At least one child still playing, so dad nods off.
Kid #1 done playing... runs back to dad.
Kid #2 done playing... runs back to dad.
Kid #4 done playing... runs back to dad.
Kid #3 done playing... runs back to dad.
Kid #5 done playing... runs back to dad.
Dad wakes up! All children accounted for. Good job, dad!
myth22> static void reapChild(int sig) {
pid_t pid;
while (true) {
pid = waitpid(-1, NULL, WNOHANG);
if (pid <= 0) break;
printf("Job %d removed from job list.\n", pid);
}
exitUnless(pid == 0 || errno == ECHILD, kWaitFailed,
stderr, "waitpid failed within reapChild sighandler.\n");
}
int main(int argc, char *argv[]) {
exitIf(signal(SIGCHLD, reapChild) == SIG_ERR, kSignalFailed,
stderr, "signal function failed.\n");
for (size_t i = 0; i < 3; i++) {
pid_t pid = fork();
exitIf(pid == -1, kForkFailed,
stderr, "fork function failed.\n");
if (pid == 0) {
char *listArguments[] = {"date", NULL};
exitIf(execvp(listArguments[0], listArguments) == -1,
kExecFailed, stderr, "execvp function failed.\n");
}
snooze(1); // represents meaningful time spent
printf("Job %d added to job list.\n", pid);
}
return 0;
}myth22> ./job-list-synchronization
Wed Oct 11 9:45:41 PDT 2017
Job 26874 removed from job list.
Job 26874 added to job list.
Wed Oct 11 9:45:42 PDT 2017
Job 26875 removed from job list.
Job 26875 added to job list.
Wed Oct 11 9:45:43 PDT 2017
Job 26876 removed from job list.
Job 26876 added to job list.
myth22>
int main(int argc, char *argv[]) {
exitIf(signal(SIGCHLD, reapChild) == SIG_ERR, kSignalFailed,
stderr, "signal function failed.\n");
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
for (size_t i = 0; i < 3; i++) {
sigprocmask(SIG_BLOCK, &mask, NULL);
pid_t pid = fork();
exitIf(pid == -1, kForkFailed,
stderr, "fork function failed.\n");
if (pid == 0) {
sigprocmask(SIG_UNBLOCK, &mask, NULL);
char *listArguments[] = {"date", NULL};
exitIf(execvp(listArguments[0], listArguments) == -1,
kExecFailed, stderr, "execvp function failed.\n");
}
snooze(1);
printf("Job %d added to job list.\n", pid);
sigprocmask(SIG_UNBLOCK, &mask, NULL); // begin handling SIGCHLD signals again
}
return 0;
}
myth22> ./job-list-synchronization
Wed Oct 11 9:49:23 PDT 2017
Job 29619 added to job list.
Job 29619 removed from job list.
Wed Oct 11 9:49:24 PDT 2017
Job 29620 added to job list.
Job 29620 removed from job list.
Wed Oct 11 9:49:25 PDT 2017
Job 29621 added to job list.
Job 29621 removed from job list.
myth22>int kill(pid_t pid, int signum);
static pid_t pid;
static int counter = 0;
static void parentHandler(int unused) { static void childHandler(int unused) {
counter++; counter += 3;
printf("counter = %d\n", counter); printf("counter = %d\n", counter);
kill(pid, SIGUSR1); }
}
int main(int argc, char *argv[]) {
signal(SIGUSR1, parentHandler);
if ((pid = fork()) == 0) {
signal(SIGUSR1, childHandler);
kill(getppid(), SIGUSR1);
return 0;
}
waitpid(pid, NULL, 0);
counter += 7;
printf("counter = %d\n", counter);
return 0;
}myth22> ./kill-puzzle
counter = 1
counter = 8
myth22> ./kill-puzzle
counter = 1
counter = 3
counter = 8
myth22>