A brief analysis of how to invoke Linux script _c language in C language

Source: Internet
Author: User
Tags win32

First, the introduction
Fork is one of the most difficult concepts for anyone who has not touched the Unix/linux operating system: it executes once and returns two values. The fork function is one of the most outstanding achievements of the UNIX system, and it is the result of the early developer of Unix in the 70, after a long period of hard exploration in theory and practice, on the other hand, it makes the operating system pay the lowest cost in process management, on the other hand, It also provides a simple and straightforward method for programmers to process multiple processes. Unlike DOS and earlier Windows, the Unix/linux system is a truly multitasking system, and it can be said that without the use of multiple process programming, it is not a real Linux environment programming.

The concept of multithreaded programming was put forward in the 60 's, but it was not until the middle of the 80, the UNIX system introduced multithread mechanism, now, because of its many advantages, multithreaded programming has been widely used.

Below, we'll introduce some preliminary knowledge of how to write multiple processes and multithreaded programs under Linux.

Two, multi-process programming
What is a process? The concept of the process is for the system rather than the user, and for the user, the concept he faces is the program. When a user typing a command to execute a program, it will initiate a process for the system. However, unlike a program, in this process, the system may need to start one or more processes to complete a number of independent tasks. The main content of multi process programming includes process control and interprocess communication, before we know it, we need to understand the structure of the process first.

2.1 The structure of the process under Linux
The next Linux process has three parts of data in memory, code snippets, stack segments, and data segments. In fact, learn assembly language people must know, the general CPU has the above three kinds of register, in order to facilitate the operation of the operating system. These three parts are also necessary parts to form a complete execution sequence.

"Code Snippet", as the name implies, is the data stored in the program code, if there are several processes in the machine running the same program, then they can use the same code snippet. The stack segment holds the return address of the subroutine, the parameters of the subroutine, and the local variables of the program. The data segment then holds the program's global variables, constants, and the data space allocated by the dynamic data (such as the space obtained by functions such as malloc). There are a lot of details, which are limited to the length of this article. If the system runs several identical programs at the same time, they cannot use the same stack segment and data segment.

Process Control under 2.2 Linux
In a traditional UNIX environment, there are two basic operations for creating and modifying processes: the function fork () is used to create a new process that is almost a full copy of the current process; the function family exec () is used to start another process to replace the currently running process. Linux Process Control is basically consistent with traditional UNIX process control, with only a few details, such as calling Vfork and fork exactly the same in Linux, while Vfork calls have different capabilities in some versions of UNIX systems. Since these differences hardly affect most of our programming, we are not considering this here.

2.2.1 Fork ()
Fork is the meaning of "bifurcation" in English. Why do you take that name? Because a process is running, if a fork is used, another process is created, and the process is "forked", so the name gets a very good image. Here's how to use fork specifically, which demonstrates the basic framework for using fork:

Copy Code code as follows:

void Main ()
{
int i;
if (fork () = = 0)
{
/* Subprocess Program * *
for (i = 1; I <1000; i + +)
printf ("This are child process\n");
}
Else
{
/* Parent Process Program * *
for (i = 1; I <1000; i + +)
printf ("This is Process process\n");
}
}

Once the program is running, you can see the 1000 messages printed on the screen alternately between the subprocess and the parent process. If the program is still running, you can use the PS command to see that there are two of them running in the system.

So what happens when you call this fork function? The fork function starts a new process, which, as we said earlier, is almost a copy of the current process: the child process and the parent process use the same Code snippet, and the subprocess replicates the stack segment and the data segment of the parent process. In this way, all the data for the parent process can be left to the child process, but once the subprocess is run, it inherits all the data from the parent process, but in fact the data is separated from each other, which means that they no longer share any data. They want to interact with information only through interprocess communication, which is what we'll do below. Since they are so alike, how can the system differentiate them? This is determined by the return value of the function. For the parent process, the fork function returns the process number of the subroutine, and for the subroutine, the fork function returns zero. In the operating system, we can see a different process number with the PS function, and for the parent process its process number is given by a system call that is lower than it, and for the child process, its process number is the return value of the fork function to the parent process. In programming, both the parent process and the subprocess invoke the code below the function fork (), and we use the fork () function to if...else the different return values of the parent-child process ... Statement to enable the parent-child process to perform different functions, as we have shown above. We see that the above example executes when two messages are printed without rules, and this is the result of a parent-child process being executed independently, although our code seems to be no different from serial code.

Readers may ask, if a large program is running, its data segments and stacks are very large, one fork to replicate once, then fork system overhead is not very big? In fact, UNIX has its own solution, you know, the General CPU is "page" as a unit to allocate memory space, each page is an image of the actual physical memory, like Intel's CPU, whose page is typically 4086 bytes in size, regardless of whether the data segment or stack segment is made up of many pages "Composition, the fork function copies these two segments, just" logically "on, is not" physical ", that is to say, when the actual execution of fork, the data and stack segments of the two processes in the physical space are still shared, and when a process writes a data, the data between the two processes is different. The system separates the differentiated "pages" from the physical. The space overhead of the system can be minimized.

Here is a small program that is enough to "kill" Linux, and its source code is very simple:

Copy Code code as follows:

void Main ()
{
for (;;)
{
Fork ();
}
}

This program does nothing, that is, the death cycle of fork, the result is that the process continues to produce processes, and these processes continue to produce new processes, soon, the system process is full, the system has been so many ongoing processes "to death." Of course, as long as the system administrator gives each user the maximum number of processes to run, the malicious program will not be able to complete the attempt.

2.2.2 Exec () function family
Let's take a look at how a process can start another program's execution. Use the EXEC function family in Linux. The system call EXECVE () replaces the current process with a specified program whose parameters include a filename (filename), a parameter list (argv), and an environment variable (ENVP). The EXEC function family of course more than one, but they are roughly the same, in Linux, they are: Execl,execlp,execle,execv,execve and EXECVP, I only take EXECLP as an example, the other functions and EXECLP what is the difference between Please use the manexec command to learn more about them.

Once a process calls the Exec class function, it itself "dies", the system replaces the code snippet with the new program code, discards the original data segment and stack segment, and assigns new data segments and stack segments to the new program, the only thing left is the process number, that is, the system, or the same process, But it's already another program. (However, some of the Exec class functions also allow the inheritance of information such as environment variables.) )

So what if my program wants to start another program and still want to run it? That is combined with the use of fork and exec. The following code shows how to start running other programs:

Copy Code code as follows:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

Char command[256];
void Main ()
{
int RTN; /* The return value of the child process * *
while (1) {
/* Read the command to be executed from the terminal * *
printf (">");
Fgets (command, 256, stdin);
Command[strlen (command)-1] = 0;
if (fork () = = 0) {/* subprocess executes this command * *
EXECLP (command, NULL);
/* If the EXEC function returns, it indicates that the command is not being executed properly, print the error message * *
perror (command);
Exit (errno);
}
else {/* parent process, wait for child process to finish, and print child process return value * *
Wait (&AMP;RTN);
printf ("Child process return%d\n", RTN);
}
}
}


This program reads the command from the terminal and executes it, and the parent process waits to read the command from the terminal after the execution completes. Friends who are familiar with DOS and Windows system calls must know that Dos/windows also has the Exec class function, its usage is similar, but Dos/windows also has the Spawn class function, because DOS is a single task system, it can only reside "the parent process" in the machine to execute " Subprocess, which is the function of the Spawn class. WIN32 is already a multitasking system, but it retains the Spawn class function, WIN32 the method of implementing the Spawn function in the same way as in Unix, opening the subprocess Hofu the process waits for the child process to finish before running. UNIX is a multitasking system at the outset, so it is not necessary to spawn class functions from a core point of view.

In this section, we will also talk about the system () and Popen () functions. The system () function first calls fork () and then calls exec () to execute the user's login shell, which finds the executable's command and analyzes the parameters, and then uses one of the wait () function families to await the end of the child process. The function Popen () is similar to the function system (), but it calls the pipe () function to create a pipe through which to complete the standard input and standard output of the program. These two functions are designed for less diligent programmers, have considerable efficiency and security flaws, and should be avoided as far as possible.

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.