A process terminates:
A process can be registered if a (specific?? Verify the next) function, these functions are moved by exit?, these functions are called end-of-handle functions, and the ATEXIT function can register these functions. Exit tune? The order of the processing functions is the opposite of the order of atexit registrations, and if a function is registered multiple times, it will be adjusted multiple times.
The following function was called when the program was abnormally or terminated normally:
There are 8 types of process, the first 5 are normal end, and the last three are abnormal end?:
1 returns from the main function;
2-tone Exit function;
3 tune _exit or _exit;
4 The last thread is returned from the boot routine;
5 last thread tune Pthread_exit;
6-tone abort function;
7 receive a signal and end it?
8 The last thread responds to a cancellation request.
The essential difference between exit () and _exit () and _exit () functions is whether to enter the kernel immediately, _exit (), and the _exit () function to enter the kernel immediately after the call, without performing some cleanup, but exit () performs some cleanup. This is why the atexit () function exists because the exit () function needs to perform cleanup and a series of operations, which are actually the actual executions of various so-called cleanup operations.
Let's verify the execution order of the atexit:
#include <stdio.h>
#include <stdlib.h>
void Func1 () {
printf ("func1");
}
void Func2 () {
printf ("Func2");
}
void Func3 () {
printf ("func3");
}
int main () {
Atexit (FUNC1);
Atexit (FUNC2);
Atexit (FUNC3);
return 1;
}
Execution result: You can see that the Atexit function's call order and the order of registration are reversed
Func3
Func2
Func1
Two command-line arguments and environment tables
When executing a program, command-line arguments can be passed to the program by using the ARGC and argv parameters in the main function
int main (int argc,char *argv[]) {
for (int j=0;j<argc;j++) {
printf ("argc[%d]:%s\n", J,argv[j]);
}
}
Execution results. The first parameter is a specific command line.
[Email protected]:/home/zhf/c_prj#./chapter7 arg1 arg2 Arg3
Argc[0]:./chapter7
Argc[1]:arg1
Argc[2]:arg2
Argc[3]:arg3
Environment table:
Each program receives an environment table. As with the parameter table, the environment table is also an array of character pointers, where each pointer contains an address to a null-terminated C string. The global variable environ contains the address of the array of pointers.
The calling method is as follows:
extern char **environ;
int main (int argc,char *argv[]) {
for (int i=0;environ[i]!=null;i++) {
printf ("%s\n", Environ[i]);
}
return 1;
}
But in the UNIX system actually the main function takes 3 parameters, and the third parameter is the Environment table address
int main (int argc,char *argv[],char *envp[]) {
for (int i=0;envp[i]!=null;i++) {
printf ("%s\n", Envp[i]);
}
return 1;
}
If you want to query or set a single environment variable, you need to use several functions of the operating environment variable:
Char *getenv (const char *name);
The return value of the function is the address of the value string in Name=value and returns null if it is not found.
int putenv (char *str);
int setenv (const char *name, const char *value, int rewrite);
int unsetenv (const char *name);
The putenv operation is to put the Name=value string into the environment table, and if name exists, first delete its original definition.
Setenv set name to value. If name exists in the environment, when rewrite is not 0, its existing definition is first deleted. When rewrite is 0, its existing definition is not deleted (name is not set to the new value, and there is no error);
Unsetenv Delete the definition of name. There is no error even if name does not exist.
Take a look at the specific ways to use:
Get home address by setting name= "Home"
void Getenv_function () {
Char *ret;
const char *name= "HOME";
RET=GETENV (name);
printf ("%s", ret);
}
Setting environment variables
Char str[10]= "Sex=male";
void Putenv_function () {
Putenv (str);
}
SETENV Setting Environment variables
void Setenv_function () {
Char name[10]= "name";
Char *str= (char *) malloc (20*sizeof (char));
const char *value= "ZHF";
memcpy (str,name,sizeof (name));
Setenv (str,value,1);
}
The difference between putenv and setenv:
Setenv must allocate a store to create a Name=value string based on its parameters. At the same time, putenv does not need to put the parameter string passed to it directly into the environment.
Note: When using putenv, an error occurs when a string stored in the stack is passed as a parameter to the function, because the storage area that its stack frame occupies may be reused when returning from the current function.
Linux C Programming: Process Environment