Spyrius

xiaoxiao2021-03-06  60

Spyrius is a small program written by Mr. Mark Lindner. Mr. Mark Lindner has written pingutil and cfl several kits. I found Mark from GNU

Mr. Lindner. I hope that there are many people who often go to GNU here, and they have to get their own gains and happiness.

Spyrius is a multi-threaded, universal super daemon. People who engage in Linux / UNIX should know the specific meaning of Daemon, blur

If you can imagine inetd what you do.

Spyrius listens on a TCP port, unlike some traditional daemons, you must generate a new sub-process for each client.

Accepted the service. Spyrius is a multi-threaded tool that uses each thread to process the request. One of the benefits of replacing the process of thread is sharing

The related stack resources of the process avoid the consumption of the process creation.

SPYRIUS Another feature is to modularize a particular functional service. For example, network communication, parsing packets, create threads, etc. are designed to become a PLUG-IN module,

Can be written and debugged by independent. You can combine your own Spyrius by profile. The PLUG-IN module interacts through a set of API and Daemon, of course, also provides corresponding APIs and clients to communicate.

Spyrius main program In Spyrius.c file, the management port (SpyR_ADMIN_PORT) 8381 and the service port (Spyr_Server_Port) 8380 is specified by default. Main program

Read the configuration parameters from the command line, which contains: -a specified management port, namely spyr_admin_port -p specifies the service port, namely spyr_server_port -t specifies the task run timeout time -w Specifies the maximum work of Worker threads. -C reads the corresponding profile. Of course, if you do not use the command line parameters, Spyrius has the default default specified. 87-174 line After using the getopt processing to complete the command line parameters, the program starts to create a daemon, the process first, the parent process exits the program, the child process call

Spyr_daemon_init to complete some operations into a daemon. 193: if (! Spyr_daemon_init (sp, AP)) We entered Spyr_Daemon_init, at which time the file became daemon.c, the main function of this file code can also be seen from the name. At 93 lines

Spyr_daemon_init function. The first step, call OpenLog, turn on the log function, prepare for subsequent information output. Because the program is changed to the daemon, there is no control.

The terminal, so it is not possible to use STDOUT, STDERR to perform output. Steps to create a daemon, Mr. Stevens has mentioned that I believe that all the officials are familiar, I don't here.

Reflections. Next, the spyr_daemon_init function performs the creation of the service port and management port. SPYR_SOCKET_CREATE and SPYR_SOCKET_CREATE calls, respectively. After completing these two steps, the process of signal MASK settings and installation signals are installed, and the code is as follows (daemon.c: 125-138): main.c125: / * set up signal mask (Will Be inherited by Other Threads) * / 126: 127: SigfillSet (& (Act.sa_mask); 128: pthread_sigmask (SIG_BLOCK, & (ACT.SA_MASK), NULL); 129: 130: act.sa_handler = spyr_fault; 131: 132: for (i = 0; i

SPYR_MODULE_PARSECONFIG to format the configuration file specified by the command line-C, of ​​course, this part is less than the file IO and string processing, but I think that Mr. Mark Lindner is partially written, huh, huh ~ here, rough It means settings for the PLUG-IN module, the relevant structure is as follows: typedef struct module_t {int enabled; ///

You can specify the currently running thread state of a plug-in, whether to reload, whether it stops, and so on. This is done in spyr_admin. Looking at the official master

Yes, when you want to operate a thread, the code uses spyr_worker_locktable and spyr_worker_unlocktable to lock threads to avoid this process.

An error that is not synchronized. After the spyr_admin is complete, the last spyr_listen function remains left in main.c. At this time, the SPYRIUS main process is also ready, and enter the service port accept state. Listen.c0101 void spyr_listen () 0102 {0103 INT CS; 01040105 for (;;;) 0106 {0107 IF ((CS = SPYR_SOCKET_ACCEPT (MS)) <0) 0108 CONTINUE; 01090110 ELSE IF (SpyR_Worker_create (CS) <0) A accept is used in spyr_socket_accept to enter the blocking state, such as the 0184 line code. Socket.c0178 int spot_socket_accept (socket_t * s) 0179 {1080 int CS; 0181 0182 / * Accept a connection * / 0183 0184 if ((cs = accept (S-> SD, (Struct SockAddr *) & (SIN) ), & (S-> Slen))) <0) 0185 {0186 Syslog (log_warning, "accept ():% s", strrror (errno)); 0187 return (-1); 0188} 01890190 Spyr_socket_unblock (cs) 0191 0192 Return (CS); 0193} Learn to pay attention to the spyr_socket_unblock function of the 0190 row, this function will use the CS returned by Accept to the unblock process, which is set to non-blocking state, which is simple, but in the network In the server, the effect is very obvious using non-blocking IO (Non-block IO). In particular, it is necessary to handle multiple connections. I have written a non-blocking IO program test, Server accepts the large data transfer information of the Client, and the information received will be written, and the benefits

After using a single buffer, set the socket description word and file description word to non-blocking SELECT, the previous time is reduced several times. SPYR_LISTEN After completing Accept (Set the port to Non-block), spyr_worker_create creates a Worker thread. Let's follow: worker.c0096 int spotr_worker_create (int SD) {Int worker;

Spyr_worker_locktable ();

IF (nWorkers == config.Workers) {spyr_worker_unlocktable (); return (-1);

/ * Find Free Worker Slot * /

For (worker = 0; worker

/ * SET UP WORKER ENTRY * /

Workers [worker] .sd = sd; workers [worker] .active = 1; workers [worker] .when = time (null); workers [worker] .timeout = spyr_dfl_timeout; workers [worker] .logtype = spyr_log_syslog;

IF (! SPYR_SOCKET_GETPEERNAME (SD, Workers [worker] .addr, spyr_max_addrlen - 1)) STRCPY (Workers [worker] .addr, ""); strcpy (workers [worker] .label, "-");

Pthread_attr_init (& (Workers [Worker] .attr); pthread_attr_setdetachState (& (Workers [worker] .attr), pthread_create_detached;

/ * spawn worker * /

Pthread_create (& (Workers [worker] .thread), & (void *) spyr_server, (void *) & (workers [worker])); nWorkers ; spyr_worker_unlocktable ();

Return (Worker); 0155} I have no marking line number because of the length of the space. We see, first, spyr_worker_locktable lock, prevent global variables, config.Workers, and judgment

Current WORKERS NWORKERS does NWORKERS reach the maximum number of configured specified. If this is reached, this connection will be turned off and return information "TOSY". No way, current

Worker is busy, huh, huh. When there is an idle WORKER resource available, you can scan all "slots" for Workers. Describe with "slot", look at the official master feel

Is it like? When you find an idle "slot" (Workers.Active is False), the related settings are performed, such as Socket description, timeout, and so on. Next, newly created line

Cheng is placed in this "slot" and is specified for Spyr_Server. Of course, NWORKERS is at this time. Then unlock, this lock time is long :) Look at spyr_server: listen.c0124 void * spyr_server (worker_t * self) I am getting lazy, the code is too lazy, huh, huh. Continue to say, SPYR_SERVER code is at the beginning, cancel the point of the current work thread.

Off Set, there are two functions: 0132 pthread_setcancelState (pthread_cancel_enable, & x); 0133 pthread_setcanceltype (pthread_cancel_deferred, & x); Cancellation, unknown, can take a look at the POSIXTHREAD manual. Next, set a callback when the thread exits: 0137 pthread_cleanup_push ((void *) spyr_worker_cleanup, (void *) self); Well, now look at spyr_worker_cleanup done: Worker.c0170 void spyr_worker_cleanup (void * arg) 0171 {0172 worker_t * w = (worker_t *) arg; 01730174 spyr_worker_locktable (); 01750176 w-> active = 0; 0177 spyr_socket_shutdown (w-> sd); 0178 nworkers -; 01790180 pthread_attr_destroy (& (w-> attr)); 01810181 Spyr_worker_unlocktable (); 0182} Oh, when the thread work is completed, set the occupied Worker "slot" to 0 (W-> Active = 0;), indicate idle, then turn the socket port (spyr_socket_shutdown), will nWorkers -, when there is a new request, will not judge an error (Remember the judgment started by spyr_worker_create?)

Finally, the "slot" information will be destork (thread_attr_destroy). it is good! Here, we have seen a process of creation and dying in the WORKER thread. SPYR_SERVER The remaining portion is roughly the code that performs dynamically loaded PLUG-IN section and the Socket description word IO is not described. The last part of the function

Use 0336 pthread_cleanup_pop (1); 0338 pthread_exit (null); a good end of this thread. At this point, the SPYRIUS code processing framework has been completed. Spyrius is characterized by using the thread instead of the child process to handle the connection from the client. This advantage is to avoid the consumption caused by the inter-process communication, followed by avoiding

Free to create a new process to generate the consumption. But the disadvantages are also obvious. Any Worker thread will result in the entire Spyrio's collapse. Especially when

When the Worker thread executes user code, it is difficult to expect what code to write from the client programmer (referring to the errors and unstable errors caused by the plug-in part). SPYRIUS Another disadvantage is that there is no SPAWN a group of worker threads. (Of course, the creation of threads may be very fast.) If you can start some spawn

The WORKER thread will be higher in the efficiency of the system. Similarly, on the exit of the Worker thread, consider is not very perfect. You should consider the following questions: WORKER thread should exit if the current task is completed? Still

After some conditions, exit (timeout below the fixed number of workers? All of this may be described in a "threadpool", spyrius lacks one

A good thread pool. And Mark Lindner had several E-mail communication, and he also said that it is necessary to improve these places, but unfortunately more than a year, not only the code is not written, spyrius I have almost forgot, write this article Article, do some commemorative! :(Link: Spyrius in Freshmeat: http://freshmeat.net/projects/spyrius/

Originally from my blogdriver: http://manari.blogdriver.com

转载请注明原文地址:https://www.9cbs.com/read-118926.html

New Post(0)