Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the state thread source code of the open source c language network protocol library used by srs

2025-01-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

The main content of this article is to explain "what is the state thread source code of the open source c language network protocol library used by srs". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "what is the state thread source code of the open source c language network protocol library used by srs?"

State thread is an open source c language network protocol library, which implements collaborative scheduling in user space.

St was originally spun off from Netscape's MSPR (Netscape Portable Runtime library) project, followed by SGI (Silicon Graphic Inc) and Yahoo! The company (the former is the main force) jointly develop and maintain.

Since the release of v1.0 in 2001, it has not changed since the stable version of v1.9 in 2009.

State Threads: callback Terminator (required)

Https://blog.csdn.net/caoshangpa/article/details/79565411

St-1.9.tar.gz is the original, http://state-threads.sourceforge.net/

State-threads-1.9.1.tar.gz is a modified version of srs, https://github.com/ossrs/state-threads

St source code compilation

Tar zxvf st-1.9.tar.gz

Cd st-1.9

The make linux-debug / / make command can view supported compilation options

The obj directory has compiled files st.h and lib*.so,lib*.a

There are several examples of the examples directory lookupdns,proxy,server

The knowledge points needed

1 Assembly language (optional)

Stack management of 2 threads (optional)

3 scheduling and synchronization of threads (must). Test code thread.c with unsynchronized threads

4 the use of setjmp/longjmp (must). Test code setjmp.c

5 principle and use of epoll (must). Test the code epoll_server.c and epoll_client.c

Test code and document download address

Link: https://pan.baidu.com/s/1kQz3S1YIt6zUwMKScrnHaQ

Extraction code: pu9z

The purpose of analyzing the state_thread source code is to use it correctly

Thread in st is actually the concept of cooperative process.

St_xxx is divided into io class and delay class.

Some important data structures

_ st_vp_t _ st_this_vp; virtual processor virtual processor

_ st_thread_t * _ st_this_thread

_ st_clist_t run_q, io_q, zombie_q, thread_q

_ st_thread_t * idle_thread, * sleep_q

Code analysis

The example business logic that comes with the st library is more complex. If you are interested, you can take a look at it.

In order to simplify the problem, the test code st-1.9/examples/st_epoll.c is written, and the problem analysis problem is put forward according to this code.

What did st_init () do?

What does _ st_idle_thread_start () do?

What did st_thread_create () do?

What did st_thread_exit () do?

What did st_usleep () do?

How is the master business logic (infinite loop) collaboration scheduled?

How is the monitored file descriptor scheduled?

How does the cooperative process exit normally?

1 the co-program without setting the termination condition variable (cannot be join) can be exited directly by return

2 when you set the termination condition variable (which can be join) to exit the co-program, first add yourself to the zombie_q, and then notify the waiting co-program, and after the waiting co-program exits, you are quitting.

What is the meaning of the join (connection) of the cooperative process?

1 when creating a protocol a, st_thread_create (handle_cycle, NULL, 1, 0) should be set to 1, indicating that the protocol can be join.

2 st_thread_join (thread, retvalp) is not used in the coprogram b code, which means that I want to join to the coroutine a

3 join means that there are certain related lines between co-program an and co-program b. When a co-program exits, it is necessary to exit co-program b before it can exit co-program a.

4 in st, a co-program can only be join by another co-program, not by multiple co-programs join.

5 can be used by join's co-program a, which cannot exit normally when there is no other join.

What is the use of mutex in st?

In general, the multiprotocol of st does not need to be locked, but in some cases locks are required to ensure atomic operation, which is described in more detail below.

St_mutex_new (void); create lock

St_mutex_destroy (st_mutex_t lock); waiting queue must be empty to destroy the lock

St_mutex_lock (st_mutex_t lock); the lock can be acquired the first time it is deactivated, and then the waiting queue that will join the lock will be added later (FIFO)

St_mutex_unlock (st_mutex_t lock); releases the lock and activates the protocol waiting for the queue

St_mutex_trylock (st_mutex_t lock); attempts to acquire locks will not be added to the waiting queue

What is the use of cond in st?

In general, the multi-program of st does not need conditional variables, but in some cases, conditional variables are needed to ensure the order of execution of the program. For example, program a should be executed before program b.

St_cond_new (void); create condition variables

St_cond_destroy (st_cond_t cvar); the waiting queue must be empty to destroy the condition variable

St_cond_timedwait (st_cond_t cvar, st_utime_t timeout); time-limited wait condition variable, which is added to the waiting queue of the condition variable (FIFO) and added to the sleep_q queue (which may be scheduled before FIFO)

St_cond_wait (st_cond_t cvar); the blocking wait condition variable is added to the wait queue of the condition variable (FIFO)

St_cond_signal (st_cond_t cvar); wake up a co-program blocked on a condition variable

St_cond_broadcast (st_cond_t cvar); wakes up all collaborations blocked on condition variables

This diagram should be matched with the test code st-1.9/examples/st_epoll.c

Scheduling-related functions in st

Setjmp of st

# define _ ST_SWITCH_CONTEXT (_ thread)\ one of the two macro functions for co-program switching to stop the current co-program and run other co-programs

ST_BEGIN_MACRO\

ST_SWITCH_OUT_CB (_ thread);\ the function called when the co-program cuts out, generally does not work.

If (! MD_SETJMP ((_ thread)-> context))\ Assembly language implementation should return 0 for the first time like setjmp ()

{\\

_ st_vp_schedule ();\ Core scheduling function

}\

ST_DEBUG_ITERATE_THREADS ();\

ST_SWITCH_IN_CB (_ thread);\ the function called when the co-program is switched back, generally does not work.

ST_END_MACRO

Longjmp of st

# define _ ST_RESTORE_CONTEXT (_ thread)\ one of the two macro functions for co-program switching to resume thread running

ST_BEGIN_MACRO\

_ ST_SET_CURRENT_THREAD (_ thread);\ set the global variable _ st_this_thread = _ thread

MD_LONGJMP ((_ thread)-> context, 1);\ Assembly language implementation should be the same as longjmp (), and the return value is always 1

ST_END_MACRO

When MD_SETJMP, assembly will be used to retain all the register information, while MD_LONGJMP will reload all the register information. When the two are used together, the jump between functions can be completed.

Core scheduling function of st

Void _ st_vp_schedule (void)

{

_ st_thread_t * thread

Printf ("in _ st_vp_schedule\ n")

Printf ("_ st_active_count =% d\ n", _ st_active_count)

If (_ ST_RUNQ.next! = & _ ST_RUNQ)

{

Printf ("use runq\ n")

/ * Pull thread off of the run queue * /

Thread = _ ST_THREAD_PTR (_ ST_RUNQ.next)

_ ST_DEL_RUNQ (thread)

}

Else

{

Printf ("use idle\ n")

/ * If there are no threads to run, switch to the idle thread * /

Thread = _ st_this_vp.idle_thread

}

ST_ASSERT (thread- > state = = _ ST_ST_RUNNABLE)

/ * Resume the thread * /

Thread- > state = _ ST_ST_RUNNING

_ ST_RESTORE_CONTEXT (thread)

}

St auxiliary scheduling function

Void * _ st_idle_thread_start (void * arg)

{

Printf ("Isimm in _ st_idle_thread_start ()\ n")

_ st_thread_t * me = _ ST_CURRENT_THREAD ()

While (_ st_active_count > 0)

{

/ * Idle vp till Imax O is ready or the smallest timeout expired * /

Printf ("call _ st_epoll_dispatch ()\ n")

_ ST_VP_IDLE (); handles io class events

/ * Check sleep queue for expired threads * /

_ st_vp_check_clock (); handle delay events

Me- > state = _ ST_ST_RUNNABLE

_ ST_SWITCH_CONTEXT (me); resume operation from here, and then determine the value of _ st_active_count

}

/ * No more threads * /

Exit (0); the whole program exits

/ * NOTREACHED * /

Return NULL

}

What are the functions that trigger the protocol switch?

Sched.c:86: _ ST_SWITCH_CONTEXT (me); 59 int st_poll (struct pollfd * pds, int npds, st_utime_t timeout)

Sched.c:234: _ ST_SWITCH_CONTEXT (me); 221 void * _ st_idle_thread_start (void * arg)

Sched.c:261: _ ST_SWITCH_CONTEXT (thread); 244 void st_thread_exit (void * retval)

Sched.c:276: _ ST_SWITCH_CONTEXT (thread); 244 void st_thread_exit (void * retval)

Sync.c:131: _ ST_SWITCH_CONTEXT (me); 115 int st_usleep (st_utime_t usecs)

Sync.c:198: _ ST_SWITCH_CONTEXT (me); 180 int st_cond_timedwait (_ st_cond_t * cvar, st_utime_t timeout)

Sync.c:315: _ ST_SWITCH_CONTEXT (me); 290 int st_mutex_lock (_ st_mutex_t * lock)

Sched.c:134: _ ST_RESTORE_CONTEXT (thread); 115 void _ st_vp_schedule (void)

Interrupt in st

It shows that calling void st_thread_interrupt (_ st_thread_t * thread) will set the interrupt status of the protocol, and the interrupt status will interrupt this run of the program (which may be a circular task). Whether it causes the program to exit depends on the processing of the interrupt return value within the program. Let's take the st_usleep () function as an example.

[ykMac:st-1.9] # grep-nr "_ ST_FL_INTERRUPT" *

Macro definition of common.h:311:#define _ ST_FL_INTERRUPT 0x08 interrupt

Sched.c:68: if (me- > flags & _ ST_FL_INTERRUPT) 59 int st_poll () to determine whether to set interrupt when calling the function

Sched.c:70: me- > flags & = ~ _ ST_FL_INTERRUPT; exit if set, reverse interrupt before exit

Sched.c:107: if (me- > flags & _ ST_FL_INTERRUPT) 59 int st_poll (), which determines whether to set interrupt when running the protocol.

Sched.c:109: me- > flags & = ~ _ ST_FL_INTERRUPT; exit if set, reverse interrupt before exit

Sched.c:551: thread- > flags | = _ ST_FL_INTERRUPT; is set to interrupt in 545 void st_thread_interrupt ()

Sync.c:119: if (me- > flags & _ ST_FL_INTERRUPT) {115int st_usleep (st_utime_t usecs), when calling a function

Sync.c:120: me- > flags & = ~ _ ST_FL_INTERRUPT

Sync.c:133: if (me- > flags & _ ST_FL_INTERRUPT) {115int st_usleep (st_utime_t usecs), becomes runtime

Sync.c:134: me- > flags & = ~ _ ST_FL_INTERRUPT

Sync.c:185: if (me- > flags & _ ST_FL_INTERRUPT) {180 int st_cond_timedwait (), when calling a function

Sync.c:186: me- > flags & = ~ _ ST_FL_INTERRUPT

Sync.c:208: if (me- > flags & _ ST_FL_INTERRUPT) {180 int st_cond_timedwait (), becomes the runtime

Sync.c:209: me- > flags & = ~ _ ST_FL_INTERRUPT

Sync.c:294: if (me- > flags & _ ST_FL_INTERRUPT) {290 int st_mutex_lock (), when calling a function

Sync.c:295: me- > flags & = ~ _ ST_FL_INTERRUPT

Sync.c:319: if ((me- > flags & _ ST_FL_INTERRUPT) & & lock- > owner! = me) {290 int st_mutex_lock (), variable runtime

Sync.c:320: me- > flags & = ~ _ ST_FL_INTERRUPT

115 int st_usleep (st_utime_t usecs)

116 {

17 _ st_thread_t * me = _ ST_CURRENT_THREAD ()

one hundred and eighteen

119 if (me- > flags & _ ST_FL_INTERRUPT) {

120 me- > flags & = ~ _ ST_FL_INTERRUPT; reverse interrupt before exiting

121 errno = EINTR

122 return-1; if the errno or return value is not processed, the loop will continue

123}

one hundred and twenty four

125 if (usecs! = ST_UTIME_NO_TIMEOUT) {

126 me- > state = _ ST_ST_SLEEPING

127th _ ST_ADD_SLEEPQ (me, usecs)

128} else

129 me- > state = _ ST_ST_SUSPENDED

one hundred and thirty

131c _ ST_SWITCH_CONTEXT (me)

one hundred and thirty two

133 if (me- > flags & _ ST_FL_INTERRUPT) {

134For me- > flags & = ~ _ ST_FL_INTERRUPT

135 errno = EINTR

136 return-1

137}

one hundred and thirty eight

139 return 0

140}

Advantages and disadvantages of st

Advantages:

The main results are as follows: (1) the cooperative scheduling is realized in user space, which reduces the switching between user space and kernel space, and improves the program efficiency to a certain extent.

2 because it is a single thread and multiple co-programs on a single core, only one co-program is running at a time, so there is no need to do co-program synchronization for global variables.

The shared resource release function only needs to be reentrant. The so-called reentrant is to determine whether it is a null value before release and assign a null value after release.

(3) after the co-program is used, return can be done directly. St will reclaim the resources of the co-program and switch it.

4 priority scheduling can be achieved by adding a cooperative program to the header of the run_q linked list.

5 st supports multiple operating systems, such as AIX,CYGWIN,DARWIN,FREEBSD,HPUX,IRIX,LINUX,NETBSD,OPENBSD,SOLARIS

Disadvantages:

1 all API O operations must use the API provided by st, so that the co-program can be managed by the scheduler.

2 sleep () cannot be used in all protocols. Sleep () will cause the entire thread to sleep.

(3) the running time of the scheduled co-program will not be limited, and if there is a cpu-intensive or endless loop, it will seriously hinder the operation of other co-programs.

4 single process, single thread, can only use single core, if you want to improve the concurrency ability through multiple cpu, you can only open multiple programs (processes), and multi-process communication is more troublesome.

Supplementary knowledge points

Why should 1 threads be synchronized?

Threads are automatically scheduled by the kernel

Threads on the same process share the entire virtual address space of that process

The thread code area on the same process is shared, that is, different threads can execute the same function.

Therefore, in the concurrent environment, multiple threads write to the same memory address at the same time, due to the problem of CPU register time scheduling, the write data will be overwritten many times, resulting in shared data damage, so it is necessary to make threads synchronized.

2 under what circumstances is thread synchronization required?

Thread synchronization means that it does not happen at the same time, that is, threads have to queue up.

1 multi-core, single-process multi-thread, different threads will read and write global variables, in this case, it is necessary to synchronize the thread

2 single-core, single-process multi-thread, different threads will read and write global variables, in this case, there is no need to synchronize the thread.

(3) Multi-core, single-process and multi-thread, and different threads do not read or write global variables. In this case, there is no need to synchronize the thread.

4 multi-core, single-process and multi-thread, different threads will read global variables, in this case, there is no need to synchronize the thread.

Problem: for Article 2, this should be a little one-sided, dependent and priority preemption should also be synchronized, unless several threads like abcde do the same thing, and projects are not dependent on each other.

Dependency can be understood as the relationship between production and consumption. Although it is a single core, single process and multi-thread, only one thread can be running at the same time, that is, production and consumption will not occur at the same time, and multiple production will not occur at the same time. So no locks are needed.

Threads have priority control, but no matter how they are controlled, as long as only one thread is running at a time, there is no need for a lock.

Problem: for Article 2, this should be a bit one-sided, with atomic operations and thread switching during atomic operations, which requires a lock.

For example, thread a reads the global variable x for the first time and processes it, then switches back after the thread switch (the thread is scheduled automatically), and then reads the global variable x for the second time and processes it. We want to make sure that we read it twice.

The x value is the same, but if a thread switch occurs, the x value may be changed.

How do you ensure that the first read and process and the second read and process are atomic operations? Use st_mutex_t

3 accept () serialization

Also known as the shock group effect, also known as the Zeeg problem

Https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/articles/SerializingAccept.html

After fork itself many times, each process will generally begin to block on accept ()

Every time a connection is attempted on socket, the accept () of each process blocked on accept () is awakened.

Only one of the processes can actually receive the connection, and the remaining processes will get a boring EAGAIN, which leads to a lot of waste of CPU cycles. The practical solution is to serialize its use by placing a lock before the accept () call.

4 Internet Applications network program architecture

Multi-process architecture Multi-Process

One process serves one connection, to solve the problem of data sharing

Single-process multithreaded architecture Multi-Threaded

One thread serves one connection, to solve the problem of data synchronization

Event-driven State Machine Architecture Event-Driven State Machine

Event-triggered callback function (the disadvantage is nesting) or user space to implement collaborative scheduling

In fact, the EDSM architecture simulates multithreading in a very complex way

What st provides is the EDSM mechanism, which implements cooperative scheduling in user space.

At this point, I believe you have a deeper understanding of "what is the state thread source code of the open source c language network protocol library used by srs?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report