Talking about the Code Collaboration in C # Corutine

xiaoxiao2021-03-06  112

Original: http://www.blogcn.com/User8/flier_lu/index.html? Id = 3409568

A few months ago I have roughly analyze the implementation principle of the Iterator Block mechanism in C # 2.0, "Analysis of the Improvement and Improvement of Iterators in C # 2.0", and the text is briefly introduced how C # 2.0 is compiled by compilation of the CLR without modifying the CLR. The Yield keyword in the Iterator Block is implemented by a finite state machine. In fact, the ultimate goal of this mechanism is to provide a support mechanism for code collaboration.

The following is the program code: use system.collections.generic; public class tokens: ienumerable {public ienumerator getEnumerator () {for (int i = 0; i

During this code execution, Foreach's cyclic body and the getENUMERATOR function body are actually performed alternately in the same thread. This is a collaborative execution mode between threads and sequential execution, which is called collaboratively because the scheduling between multiple code blocks executed is completed by logic implicit. In order to perform, there is an indiscriminate performance, and threads are often mandatory by system scheduling programs. Relatively, the exclusive multitasks in Win3.x are similar to the collaborative model.

In terms of collaboration, it can be divided into behavior, control two parts, and control can be further subdivided into control logic and control. The behavior corresponds to how to handle the target object, in the above code: behavior is to print target objects to the console; how to traverse this Elements array, can further subdivide the control logic (order traversal) and control status (current traversal Which element is. These logic will be described in this logic to implement and simulate these logic in different languages.

Spark Gray has a series of articles on its blog to introduce some concepts of collaborative execution.

Iterators in ruby ​​(Part - 1)

Warming up to using itrators (part 2)

Articles 1, 2 Some of the Ruby language (syntax similar python) describes how the Iterator mechanism simplifies the code of traversal operation. In fact, the central idea is to separate behavior and control, and reduce the work of the control code from the support of the language level.

The following is program code: DEF textFiles (DIR) Dir.chdir (DIR) DIR ["*"]. Each do | Entry | Yield Dir "/" Entry if /^.*.txt $/ = ~ Entry if Filetest .directory? (entry) {| file | yield dir "/" file} end end dir.chdir (".." [IMG] /images/wink.gif [/ img] endtextFiles ("C: / ") {| File | PUTS file}

For example, in the recursive directory processing code of the Ruby above, synergistic support support is fully similar to C # 2.0.

The language of C # 1.0 and C does not support collaborative execution, the state migration in the process of synergy or the scheduling work of execution is required, and the library and users are required, such as the iterator itself must be saved. Location information related to traversing containers. For example, in STL implementation: The following is the program code: #include #include #include // the function Object Multiplies an element by a factortemplate class multivalue {private: Type Factor; // the value to multiply bypublic: // Constructor initializes the value to multiply by Multvalue (const type & _val [img] /images/wink.gif [/ img]: Factor (_VAL [IMG] /IMAGES/Wink.gif [/ img] {} // the function call for the element to be multiplied void operator ([img] /images/wink.gif [/ img] (Type & elem [iv] /images/wink.gif [/ img] const {ELEM * = Factor;}}; int main ([img] /images/wink.gif [/ img] {using namespace std; vector v1; // ... // using for_each to multiply each element A factor for_each (v1.begin ([img] /images/wink.gif [/ img], v1.end ([IMG] /images/wink.gif [/ img], multivalue (-2 [iv] /IMAGES/Wink.gif[/img] [img] /images/wink.gif [/ img];

Although STL is relatively successful through iterators, algorithms, and predicates, this collaborative execution logic behavior and control separation, predicate performance behavior (MultValue

, Iterators (V1.Being (), v1.end ()) performance control status, algorithm performance control logic (for_each), but still preparing complex, trouble, and semantically do not co-championship.

A mitigation method is to combine the definition of predicate and the control section, is similar to the implementation of Boost :: Lambda:

The following is program code: for_each (v.begin (), v.end (), _1 = 1); for_each (vp.begin (), vp.end (), cout << * _1 << ');

Through the magical template and macro, reduce the complexity of the independent predicate to define the behavior. However, the status and logic of the control section need to be implemented separately.

And C # 1.0 simply has no support, must pass

The example is embarrassing in the example of "the improvement of Iterators in C # 2.0".

The following program code is: public class Tokens: IEnumerable {public string [] elements; Tokens (string source, char [] delimiters) {// Parse the string into tokens: elements = source.Split (delimiters);} public IEnumerator GetEnumerator () {return new TokenEnumerator (this);} // Inner class implements IEnumerator interface: private class TokenEnumerator: IEnumerator {private int position = -1; private Tokens t; public TokenEnumerator (Tokens t) {this.t = t;} // Declare the MoveNext method required by IEnumerator: public bool MoveNext () {if (position

It's always not lacking in the cattle, huh, huh.

Ajai Shankar on the MSDN a very good article,

Corordines Implementing Corutines for .Net By Wrapping The Unmanaged Fiber API, through the Win32 API's fiber support and the support of several underlying APIs, complete a set of available collaborative implementation support mechanisms.

The pros and cons of this implementation is discussed in detail in the 4th article of Spark Gray:

SICP, Fiber API AND ITERATORS! (Part 4)

The fiber Fiber is the Win32 subsystem to port the process of the UNX under the Underdeveloped thread, and the set of lightweight parallel execution mechanisms provided by the program code self-control the scheduled flow. The method of use is simple, call ConvertThreadTofiber (EX) in a thread, and then call CreateFiber (EX) to establish multiple different fibers, and currently thread the new fiber and transition. It can be explicitly scheduled via SwitchTofiber.

The following is program code: static int arch [3] = {0, 1, 2}; static int cur = 0; Void Callback FiberProc (PVOID LPPARETER) {for (int i = 0; i = 0 ) {Std :: cout << Cur << std :: endl; switchtofiber;} deletefiber;

The above pseudo code is an approximate process used by the fiber, it can be seen that the actual fiber is very compliant with the synergistic function of the collaboration in Ruby and C # 2.0 above. In fact, the fiber is actually configured by constructing different regions in the same thread stack, switches to the specified area in the SwitchTofiber function, and enumerate such as the code (fiber) code and register. , A bit similar to the concept of longjmp in the C code base. Netscape provides status thread library

State Threads Library is a similar function that simulates mechanisms such as longjmp.

In .NET 1.0 / 1.0, the fiber is used, and it is also necessary to consider the Managed environment constructor of each fiber, and state management when switching schedule. Interested friends can read the above two wonderful articles carefully.

The following is the program code: class coria: fiber {protected {object [] array = new object [} {1, 2, 3, 4}; for (int NDX = 0; true; ndx) Yield (Arr [NDX]);}} Coroutine Next = New Coriter (); Object O = NEXT ();

It can be seen that this code is very similar to the syntax in C # 2.0, just to be subject to some details.

In C # 2.0, it is probably to ensure the transplantability, which is implemented in a manner that compiles the control logic into a state machine, and the state machine automatically manages the control state. I am in

"C # 2.0 of Iterators' improvement and implementation of the principle" has been probably analyzed, interested friends can further read

Detailed analysis in the 5th article of Spark Gray.

Implementation of Iterators IN C # 2.0 (Part 5)

as well as

Matt Pietrek About Iterator State Machine Analysis Article

Fun with itrators and state machine

In order to bind a behavior with control, C # 2.0 also provides an anonymous method support similar to the Boost :: Lambda mechanism in C . Brief analysis can refer to my previous article "The principle of the realization of the unrecognizable function of the CLR", or

SPARK GRAY's 6th article.

Implementation of Closures (Anonymous Methods) IN C # 2.0 (Part 6)

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

New Post(0)