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

How to realize the Cooperative Program in C language

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article mainly introduces the relevant knowledge of "how to realize the cooperative process in C language". The editor shows you the operation process through an actual case, and the operation method is simple, fast and practical. I hope this article "how to realize the cooperative process in C language" can help you solve the problem.

Co-program is a kind of non-preemptive thread in user space, which is mainly used to solve the problem of waiting for a large number of IO operations.

Co-programming vs thread

Instead of using multithreading to solve IO blocking tasks, the advantage of using a co-program is that there is no locking and no synchronization is needed to access the shared data. It is important to note that the reason why you do not need to lock when using a co-program is not because all co-programs run in a single thread, but because of their non-preemptive nature. In other words, if you use a co-program, you will not be suddenly switched to another co-program before handing over the CPU actively. While threads are preemptive, with multithreading you are not sure when your thread is scheduled and switched by the operating system, so you need to use locks to implement the semantics of an "atomic operation".

Co-program vs asynchronous callback

In fact, a more general and common approach is to use a non-blocking IO (such as asynchronous IO, or a set of asynchronous IO implemented on syscall, such as asio) and write the processing in the callback function. This is generally fine, but when there are more callback functions, a coherent piece of business code will be split into multiple callback functions, increasing the cost of maintenance. Therefore, using a co-program, you can write code that works asynchronously in a synchronous way.

Using static variable to realize cooperative program

To implement a co-program, the main problem is how to save the context of the function call. I saw a blog coroutines in c on the Internet before, which realized this function of saving context in a very concise way. The implementation code is as follows:

# define crBegin static int _ cr_state = 0; switch (_ cr_state) {case 0:#define crReturn (x) do {_ cr_state = _ LINE__; return x; case _ LINE__:;} while (0) # define crFinish} int func1 () {crBegin while (1) {printf ("hello world\ n"); crReturn (0);} crFinish}

This code uses the function's static variable to hold the function call state. Note that because vs2013 has a debugging feature, the implementation of vs2013's _ _ LINE__ is not constant, so it compiles and fails, and can be compiled using gcc. This code is simple but problematic, for example, if two co-programs call the same function, it will make an error. Therefore, the main purpose of mentioning this code in the blog is to give an idea, which will certainly not work if it is actually used.

Using setjmp and longjmp to realize cooperative program

As mentioned earlier, the most important thing to implement the protocol is to save the context of the function call, and these contexts are mainly divided into two parts: 1. The value of each register, 2. Function call stack. In C language, you can use setjmp to save the value of each register when the function is called. Once saved, it can be reproduced through longjmp back to the original place of setjmp (which can be understood as a cross-function goto). However, it should be noted that setjmp is only responsible for saving the value of the register, not for maintaining its function call stack (see the structure of setjmp's jmp_buf), so it is up to the user to maintain the function call stack manually. A common mistake in using setjmp and longjmp is to try to longjmp a function that has been executed. At this time, although the value of the register is the value saved at that time, the call stack is no longer the original call stack.

What I do is to apply a piece of space (2m in size) on the heap as the call stack of the co-program when creating a co-program, and then manually change the value of register esp to point to the call stack I created during setjmp. So when running later, the protocol will use the piece of memory I provided as the stack.

My protocol library provides three interfaces:

Coro_new: create a collaborator

Coro_yield: return control to the scheduling protocol

Coro_main: running the scheduling protocol

The control flow of the collaborative process is as follows:

Run the scheduling co-program through coro_main, and find out the next running co-program, run it.

Run this protocol until it calls coro_yield to return control to the dispatcher.

Repeat the above two steps until all collaborative processes have been run.

The implementation of this protocol library is very simple, with only about 100 lines of code, of course, the purpose of implementing it is to provide the simplest collaboration model, rather than a fully functional and robust one that can be put into actual business operation.

So there are a lot of questions:

For example, when the call stack exceeds 2m in the co-program, this needs to be dealt with, and the current code is not done, so it should interrupt the program to avoid writing a bad heap, resulting in random non-reproducible problems.

Obviously, multithreading is not taken into account in the implementation, and if it is run in a multithreaded environment, the code needs to be synchronized.

In this version of the protocol, there is a convention that functions called in the program cannot block in syscall, which is obviously unscientific. A complete protocol library should contain some common non-blocking implementations of syscall, after all, only one thread can't really block this call.

This is the end of the introduction of "how to realize the Cooperative Program in C language". Thank you for your reading. If you want to know more about the industry, you can follow the industry information channel. The editor will update different knowledge points for you every day.

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