0. installing and using of Cygmin
Since Cygwin was installed at the request of the teacher when taking the basic computer class, I will not introduce it here.
1. The fork() System Call
// p1.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0) {
// fork failed
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) {
// child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
} else {
printf("hello, I am parent of %d (pid:%d)\n",
rc, (int) getpid());
}
return 0;
}
The PID is different each time, which is normal.
2. The wait() System Call
// p2.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main(int argc, char *argv[])
{
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0)
// fork failed; exit
{
fprintf(stderr, "fork falied\n");
exit(1);
}
else if (rc == 0)
// child (new process)
{
printf("hello, I am child (pid:%d)\n", (int) getpid());
}
else
// parent goes down this path (main)
{
int rc_wait = wait(NULL);
printf("hello, I am parent of %d (rc_wait:%d) (pid:%dn",
rc, rc_wait, (int) getpid());
}
return 0;
}
The child will always print first.
3. The exec() System Call
// p3.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0) { // fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) { // child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
char *myargs[3];
myargs[0] = strdup("wc"); // program: "wc" (word count)
myargs[1] = strdup("p3.c"); // argument: file to count
myargs[2] = NULL; // marks end of array
execvp(myargs[0], myargs); // runs word count
printf("this shouldn’t print out");
} else { // parent goes down this path (main)
int rc_wait = wait(NULL);
printf("hello, I am parent of %d (rc_wait:%d) (pid:%d)\n",
rc, rc_wait, (int) getpid());
}
return 0;
}
The exec system call does not create a new process, but replaces the content of the original process context. The code segment, data segment, and stack segment of the original process are replaced by the new process.
4. Why? Motivating The API
// p4.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<sys/wait.h>
int main(int argc, char *argv[])
{
int rc = fork();
if (rc < 0)
{
// fork failed
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child: redirect standard output to a file
close(STDERR_FILENO);
open("./p4.output", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
// now exec "wc"...
char *myargs[3];
myargs[0] = strdup("wc"); // program: wc (word count)
myargs[1] = strdup("p4.c"); // arg: file to count
myargs[2] = NULL; // mark end of array
execvp(myargs[0], myargs); // runs word count
}
else
{
// parent goes down this path (main)
int rc_wait = wait(NULL);
}
return 0;
}
5. Process Control And Users
6. Homework(Simulation)
This simulation homework focuses on fork.py, a simple process creation simulator that shows how processes are related in a single “familial” tree. Read the relevant README for details about how to run the simulator.
Question & Answer
1
test: python forl.py -s 10
verification: python fork.py -s 10 -c
2
test: python fork.py -a 100 -f 0.1
verification: python fork.py -a 100 -f 0.1 -c
3
You can flip the question around with the -t
flag, which allows you to view process tree states and then guess what action must have taken place.
4
5
You can use different random seeds (-s flag) or just don't specify one to get different randomly generated sequences.
6
You can try more.
7. Homework (Code)
Question & Answer
1
// p1.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
int x = 100;
printf("hello world (pid:%d), x = %d\n", (int) getpid(), x);
int rc = fork();
if (rc < 0)
{
// fork failed
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child (new process)
printf("hello, I am child (pid:%d), x = %d\n", (int) getpid(), x);
}
else
{
// parent goes down this path (main)
printf("hello, I am parent of %d (pid:%d), x = %d\n",
rc, (int) getpid(), x);
}
return 0;
}
2
// p2.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/wait.h>
#include<assert.h>
int main(int argc, char *argv[])
{
printf("hello world (pid:%d)\n", (int) getpid());
// open a file
int fd = open("./openFile", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
assert(fd > -1); // open failed, exit
int rc = fork();
if (rc < 0)
{
// fork failed
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child: redirect standard outpupt to a file
printf("hello, I am child (pid:%d)\n", (int) getpid());
printf("fd = %d\n", fd);
}
else
{
// parent goes down this path (main)
printf("hello, I am parent of %d (pid:%d)\n", rc, (int) getpid());
printf("fd = %d\n", fd);
}
return 0;
}
3
// p3.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0)
{
// fork failed
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
}
else
{
// parent goes down this path (main)
int rd = fork();
if (rd == 0)
printf("goodbye, I am parent (pid:%d)\n", (int) getpid());
}
return 0;
}
4
// p4.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>
int main(int argc, char *argv[])
{
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0)
{
// fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
char *myargs[2];
myargs[0] = strdup("/bin/ls");
myargs[1] = NULL;
execvp(myargs[0], myargs);
printf("this shouldn't print out");
}
else
{
// parent goes down this path (main)
int rc_wait = wait(NULL);
printf("hello, I am parent of %d (rc_wait:%d) (pid:%d)\n",
rc, rc_wait, (int) getpid());
}
return 0;
}
5
// p5a.c wait() in the parent
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>
int main(int argc, char *argv[])
{
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0)
{
// fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
}
else
{
// parent goes down this path (main)
int rc_wait = wait(NULL);
printf("hello, I am parent of %d (rc_wait:%d) (pid:%d)\n",
rc, rc_wait, (int) getpid());
}
return 0;
}
// p5b.c wait() in the child
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>
int main(int argc, char *argv[])
{
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0)
{
// fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child (new process)
int rc_wait = wait(NULL);
printf("hello, I am child (rc_wait:%d) (pid:%d)\n", rc_wait, (int) getpid());
}
else
{
// parent goes down this path (main)
printf("hello, I am parent of %d (pid:%d)\n", rc, (int) getpid());
}
return 0;
}
6
// p6.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>
int main(int argc, char *argv[])
{
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0)
{
// fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
}
else
{
// parent goes down this path (main)
/* pid_t waitpid(pid_t pid, int* status, int options);
* if you are not familiar with this function,
* you can go to Baidu Baike, don’t be afraid of trouble.
*/
waitpid(rc, NULL, WNOHANG);
printf("hello, I am parent of %d (pid:%d)\n", rc, (int) getpid());
}
return 0;
}
7
// p7.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0)
{
// fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child (new process)
close(STDOUT_FILENO);
printf("hello, I am child (pid:%d)\n", (int) getpid());
}
else
{
// parent goes down this path (main)
printf("hello, I am parent of %d (pid:%d)\n", rc, (int) getpid());
}
return 0;
}
8
// p8.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
int main(int argc, char *argv[])
{
int fd[2];
/* fd[0] points to the read port of the pipe
* fd[1] points to the write port of the pipe
*/
int ret = pipe(fd);
if (ret == -1)
{
perror("pipe error\n");
exit(1);
}
int rc = fork();
if (rc < 0)
{
// fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
// child (new process)
close(fd[0]);
char *child = "I am child";
for (int i = 0; i < 5; i++)
{
write(fd[1], child, strlen(child) + 1);
sleep(2);
}
}
else
{
// parent goes down this path (main)
close(fd[1]);
char msg[50];
for (int i = 0; i < 5; i++)
{
memset(msg, '\0', sizeof(msg));
ssize_t s = read(fd[0], msg, sizeof(msg));
if (s > 0)
msg[s - 1] = '\0';
printf("%s\n", msg);
}
}
return 0;
}
标签:fork,Process,printf,pid,int,API,rc,习题,include
From: https://www.cnblogs.com/astralcon/p/16792680.html