The method of process and multi-process management in VC + + _c language

Source: Internet
Author: User
Tags function prototype mutex volatile

This article describes the VC + + process and multi-process management methods, share for everyone to reference. The specific methods are analyzed as follows:

absrtact : This paper mainly introduces the multi-process management technology in multi-task management, and expounds the mutual exclusion running of process, the creation and completion of the subprocess.

keywords : vc++6.0; process; environment variables; child processes

Process

The process is the next instance of the current operating system that is loaded into memory and is running. Each process is made up of kernel objects and address spaces, the kernel object allows the system to store statistics about the process and enable the system to manage processes, while the address space includes the code and data for all program modules, as well as the dynamically allocated space such as the thread stack, heap allocation space, and so on. A process is only a presence, and cannot do anything alone, it must have at least one thread running in its environment, and it is responsible for executing code within the process address space. When a process starts, a thread is also started, called the main thread or the execution thread, from which the thread can continue to create child threads. If the main thread exits, the process is not possible, and the system will automatically undo the process and complete the release of its address space.
The image of each executable file or dynamic link library file loaded into the process address space is assigned a globally unique instance handle (HINSTANCE) associated with it. The instance handle is actually a basic memory address that records the location where the process is loaded. The instance handle of the process is passed through the first parameter hinstance Hinstexe in the program entry function WinMain (), whose actual value is the address of the base address space used by the process. For VC + + linked programs linked to the resulting program, its default basic address space address is 0x00400000, if not necessary generally do not modify the value. In a program, you can get the basic address space used by the specified module through the GetModuleHandle () function.

Creation of child processes

The creation of a process is implemented through the CreateProcess () function, CreateProcess () to start and run a new program by creating a new process and a main thread running in its address space. Specifically, when executing the CreateProcess () function, the operating system is responsible for creating a process kernel object, initializing the count to 1, and immediately creating a virtual address space for the new process. The code and data for the executable file or any other necessary dynamic-link library file are then loaded into the address space. When the main thread is created, it is also the first time the system is responsible for creating a thread kernel object and initializing it to 1. Finally, the main thread is started and the process's entry function WinMain () is executed, completing the creation of the process and execution thread.
The prototype declaration for the CreateProcess () function is as follows:

Copy Code code as follows:
BOOL CreateProcess (
LPCTSTR Lpapplicationname,//executable module name
LPTSTR lpcommandline,//command line string
Lpsecurity_attributes lpprocessattributes,//process security attributes
Lpsecurity_attributes lpthreadattributes,//thread security attributes
BOOL binherithandles,//Handle inheritance Flag
DWORD dwcreationflags,//Create flag
LPVOID lpenvironment,//Pointer to new environment block
LPCTSTR lpcurrentdirectory,//pointer to current directory name
Lpstartupinfo lpstartupinfo,//pointer to startup information structure
Lpprocess_information lpprocessinformation//Pointer to process information structure
);

In the program design, a specific function module can be implemented in different forms, such as function or thread. For the same process, these functions, threads exist in the same address space, and at the time of execution, most of the data associated with it is processed. If there is some error in the algorithm, it will be possible to break some other important content of the same address space with it, which will result in more serious consequences. To protect the content in the address space, you can consider placing the part of the operation that requires access to the data in the address space to the address space of another process and allowing it to access only the relevant data in the original process address space. Specifically, a subprocess can be created in the process through the CreateProcess () function, which accesses only the related data in the parent process address space during all processing, thereby protecting all data that is not relevant to the task performed by the current child process in the parent process address space. In this case, the role of a subprocess is similar to that of a function and a thread, and can be viewed as a process during which the parent process is running. To do this, the parent process needs to master the start, execution, and exit of the subprocess. The following code shows this process:
Copy Code code as follows:
Temporary variable
CString Scommandline;
Char Cwindowsdirectory[max_path];
Char Ccommandline[max_path];
DWORD Dwexitcode;
Process_information Pi;
Startupinfo si = {sizeof (SI)};
Get the Windows directory
GetWindowsDirectory (Cwindowsdirectory, MAX_PATH);
Start the command line for the Notepad program
Scommandline = CString (cwindowsdirectory) + "//notepad.exe";
:: strcpy (Ccommandline, scommandline);
Start Notepad as a child process
BOOL ret = CreateProcess (null, ccommandline, NULL, NULL, FALSE, 0, NULL, NULL, &SI, &PI);
if (ret) {
Closes the main thread handle of a child process
CloseHandle (Pi.hthread);
Waiting for the child process to exit
WaitForSingleObject (pi.hprocess, INFINITE);
Get exit code for child process
GetExitCodeProcess (pi.hprocess, &dwexitcode);
Close child process Handle
CloseHandle (pi.hprocess);
}

This code first creates a "Notepad" program with Windows from CreateProcess () as a subprocess, and the child process initiates the Hofu process to wait for the end of its execution through the WaitForSingleObject () function. The parent process is always blocked before the child process exits, where the role of the child process is similar to that of a single-threaded function. Once the child process exits, the Pi.hprocess object that the WaitForSingleObject () function waits for will be notified, the parent process will continue, and, if necessary, the exit code of the child process can be obtained by getexitcodeprocess ().
More often than not, the parent process does not have any data exchange and communication with it after the child process is started, and the execution of the child process created by it is independent of the parent process. Many large software in the design also uses this kind of idea, will some functions complete through the independent application, when needs to carry out the operation to start the corresponding child process through the main program, the concrete processing work all completes by the subprocess. The process of creating such a subprocess is simpler, for example, for the above code simply to remove the pi.hprocess of the child process handle:
Copy Code code as follows:
BOOL ret = CreateProcess (null, ccommandline, NULL, NULL, FALSE, 0, NULL, NULL, &SI, &PI);
if (ret) {
Closes the main thread handle of a child process
CloseHandle (Pi.hthread);
Close child process Handle
CloseHandle (pi.hprocess);
}

You can set the priority of a child process through the dwCreationFlags parameter when the process is created. The preceding example code uses the default priority when creating the child process, and if you want to set the priority to high, you can modify the following:
Copy Code code as follows:
BOOL ret = CreateProcess (null, ccommandline, NULL, NULL, FALSE, high_priority_class, NULL, NULL, &SI, &PI);

If the process is created without a special priority, it can be dynamically set by the Setpriorityclass () function, which requires the handle of the process to be manipulated and the precedence identifier as the entry parameter, and the function prototype is:
Copy Code code as follows:
BOOL Setpriorityclass (HANDLE hprocess, DWORD dwpriorityclass);

For example code that is not previously set priority, you can dynamically change its priority setting by the parent process when the child process starts:
Copy Code code as follows:
Setpriorityclass (pi.hprocess, High_priority_class);

Or the child process changes its priority setting after it starts, it should be noted that the process handle should be set to the handle of the subprocess itself, and it can be obtained by the getcurrentprocess () function:
Copy Code code as follows:
HANDLE hprocess = GetCurrentProcess ();
Setpriorityclass (hprocess, High_priority_class);

Mutex run for process

Normally, the operation of a process will normally not affect other running processes. However, programs that have special requirements for hardware devices such as the exclusive use of serial ports require that other programs that attempt to use this port device not be allowed to run during their process operation, and that such programs are often not allowed to run multiple instances of the same program. This leads to the problem of mutex of the process.
The core idea of mutually exclusive process is simple: the process starts with a check that the current system already has an instance of this process, and if not, the process will successfully create and set the token that identifies the instance that already exists. The process is then created with the token knowing that its instance already exists, guaranteeing that only one instance of the process can exist in the system. It can be implemented by a variety of methods, such as memory mapping file, famous event quantity, well-known mutex and global shared variables. Here are two ways to represent a well-known mutex and a global shared variable:

Copy Code code as follows:
Create mutexes
HANDLE M_hmutex = CreateMutex (NULL, FALSE, "Sample07");
Check for error codes
if (GetLastError () = = error_already_exists) {
Disposes the handle and resets the mutex if there is an existing mutex
CloseHandle (M_hmutex);
M_hmutex = NULL;
Program exit
return FALSE;
}

The above code demonstrates the use of a well-known mutex in a process mutex. The core of the code is the creation of a CreateMutex () for a known mutex. The CreateMutex () function can be used to create a well-known or nameless mutex object whose function prototype is:
Copy Code code as follows:
HANDLE CreateMutex (
Lpsecurity_attributes lpmutexattributes,//Pointer to security attribute
BOOL Binitialowner,//Initialize the owner of the mutex
LPCTSTR lpname//Pointer to mutex object name
);

If the function executes successfully, a handle to the mutex object is returned. If a mutex with the same name already exists before CreateMutex () executes, the function returns the handle of the existing mutex, and the error code error_already_exist can be obtained by GetLastError (). Visible, CreateMutex () is mutually exclusive to the process through detection of the error code error_already_exist.

The method of using global shared variables is mainly implemented by compilers in MFC framework programs. Create a new section using the #pragma data_seg precompiled directive, where you can define a variable in the volatile keyword, and you must initialize it. The volatile keyword specifies that a variable can be accessed for an external process. Finally, in order for the variable to function in a process mutex, it is also set as a shared variable, while allowing read and write access. This can be communicated to the compiler by #pragma comment the precompiled instructions. The following is a list of process mutex codes that use global variables:

Copy Code code as follows:
#pragma data_seg ("Shared")
int volatile g_lappinstance = 0;
#pragma data_seg ()
#pragma COMMENT (linker, "/SECTION:SHARED,RWS")
......
if (++g_lappinstance>1)
return FALSE;

The purpose of this code is to add 1 to the global shared variable G_NAPPINSTANCD when the process starts, and if the value is found to be greater than 1, return false to notify the end of the process. It is important to note here that in order for the above two pieces of code to really play a role that is mutually exclusive to the process, it must be placed at the beginning of the application's entry code, the initialization instance function of the application class, InitInstance ().

End Process

Processes simply provide a section of address space and kernel objects that run through the main thread in their address space. When the entry point function of the main thread returns, the process ends. This process is terminated by a normal exit of the process, and all thread resources in the process can be properly purged. In addition to the normal rollout of this process, it is sometimes necessary to use code in a program to force the end of this process or other processes to run. The ExitProcess () function can be used in a thread in the process and will terminate the running of this process immediately. The ExitProcess () function prototype is:
VOID exitprocess (UINT uexitcode);

The parameter Uexitcode sets the exit code for the process. The function is mandatory, and the process is terminated after execution, so any code that is behind it cannot be executed. Although the ExitProcess () function can notify the dynamic link library associated with it at the end of the process, the ExitProcess () function will have a security risk due to the enforcement of this execution. For example, if a memory has been requested with the new operator before the program calls the ExitProcess () function, it will not be released by the delete operator because of the mandatory exitprocess () function, causing a memory leak. In view of the mandatory and unsafe exitprocess () function, it must be noticed when used.

ExitProcess () can only force the exit of this process, and if you want to force the end of other processes in one process, it is done with terminateprocess (). Unlike ExitProcess (), the TerminateProcess () function executes, and the terminated process does not receive any notification of the program's exit. That is, a process that is terminated cannot finish before quitting before it finishes running. Therefore, it is often considered that terminateprocess () is used to force the end of a process only if no other method can force the process to exit. The following is a function prototype for terminateprocess ():

Copy Code code as follows:
BOOL terminateprocess (HANDLE hprocess, UINT uexitcode);

The parameters hprocess and Uexitcode are process handles and exit codes, respectively. If the process is closed, you can get to the handle by GetCurrentProcess (). TerminateProcess () is executed asynchronously, and after the call returns it is not certain that the terminated process has actually exited, if the process of invoking terminateprocess () is concerned about this detail, You can wait for the real end of the process through WaitForSingleObject ().

Summary

Multi-process is the important content of multitask management, the above part of this paper introduces its basic concept and main technology such as the creation and end of subprocess, the mutual exclusion of process. The reader should be able to have a preliminary understanding of multi process management.

I hope this article describes the VC + + program to help.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.