Processes are isolated. By default, no processes can communicate with another process. Each process has their own address space.git
#include <unistd.h> /*fork declared here*/
#include <stdio.h> /* printf declared here*/
int main() {
int answer = 84 >> 1;
printf("Answer: %d", answer);
fork();
return 0;
}
複製代碼
When calling fork(), the whole memory including buffer will all be copyed.dom
If fork() return -1, somethings goes wrong. If 0, we are currently inside child process. If 1, we are currently in the parent process. We can use getpid() to get own pid, gitppid() to get parent pid. They are using the same kernel file descriptor. If one process rewinds the random access back to be beginning of file, both process will be affected.ide
pid_t pid = fork()
if(pid = -1){
perror("fork wrong");
exit(1);
}
if(pid > 0){
waitpid(pid, &status, 0);
}else{
exit(0);
}
複製代碼
We can use exec after forking. It will replace everything after exec(). So everything need to be done in child process should before exec().ui
After finished, the child process still hold a slot in kernel process table and some informations. They are only available if the child process is waited. For the short process, it doesn't matter. However, if too many zombies. There will be not enough empty slot for new processes.spa
waitpid(child, &status, 0);//will clean up and wait for child to finish
複製代碼
Environment variables are variables that all processes use.code
char* home = getenv("HOME");
setenv("HOME","home/bhuvan",1)
複製代碼
Each process get its own dictionary. If parent change their environment variable, it won't transfer to their child.orm
int status;
pid_t child_pid = fork();
if(child == -1) return 1;
if(child > 0){
pid_t pid = waitpid(child_pid,&status,0);
if(pid != -1 && WIFEXITED(status)){
int lowest8 = WEXITSTATUS(status); // A process can only have 256 return values
printf("Process %d return %d", pid, lowest8);
}
}else{
execl("/bin/ls","bin/ls",".",(char*)NULL); "ls ."
}
複製代碼
Example:cdn
int love(char* str){
printf("%s\n",str);
return 1;
}
main(){
pthread_t id;
void* result;
pthread_create(&id, NULL, love, "Wo Ai SYH.");
pthread_join(id, &status);
return;
}
複製代碼
Pthread_join() and Pthread_exit() will all give the other threads enough time to finish their work. However, pthread_exit will not wait for the return.blog
int main(){
pthread_t id1;
pthread_t id2;
pthread_create(&id1, NULL, myfun, "CNM");
pthread_create(&id2, NULL, myfun, "TMD");
pthread_exit(NULL);
}
int main(){
pthread_t id1;
pthread_t id2;
int result;
pthread_create(&id1, NULL, myfun, "CNM");
pthread_create(&id2, NULL, myfun, "TMD");
pthread_join(id1, &result);
pthread_join(id2, &result);
}
複製代碼
pthread_join() can:ip
We need to focus on the life time of stack variable. Use static or pthread_join().
int start = 42;
int result;
pthread_t tid;
pthread_create(&tid, NULL, fun, &start);
pthread_join(tid, &result);
複製代碼
The heap, global variable and other segment except stack.
We can use pthread_create to send stack variable to another thread in the same process. But we need to use pthread_join to keep the stack variable valid.
If the parent process terminated when the child process still running. The init process will become its new parent and init process will wait for every process.
If the parent don't wait for their child. There will be slot and information of that zombie holded in process table. If we are running a long-run process, there might be not enough space for new process. The thread terminated and doesn't waited is zombie process.