Two object-oriented C ++ thread models

zhaozj2021-02-12  208

Two object-oriented C thread models

Abstract: This article first analyzes the thread model compared to Java, C #, then implements a lightweight thread model CJTHREAD / IRUNABLE similar to Java in C , and uses templates and operator -> * to implement similar C #-like thread models. CCSharpthread. This article focuses on the CCSharpthread model, which is not only type security, but also the public non-static class method for any prototype DWORD () as a thread method.

Key words: C ; template; operator -> *; thread; thread model

Object-oriented thread models enable developers to view threads in object-oriented methods, and implement thread application logic with object-oriented methods; it contains two elements, packaging thread logic (such as thread creation, destruction, management, etc.) Thread objects and thread methods for implementing thread application logic. C itself does not provide an object-oriented thread model. Currently used Win32 Thread and Posix Thread only provide an API (referred to as thread API) of an C interface, and can only use normal C functions as a thread method. C non-static class membership cannot be used as a thread method due to a hidden THIS parameter, making C programmers to develop lightweight (refer to MFC, VCL, etc.) Multi-threaded applications cannot take advantage of object-oriented Methods to look at the thread. This article first analyzes the thread model of Java, C #, and then implements a lightweight thread model CJTHREAD / IRUNABLE similar to Java in C , and uses templates and operator -> * to implement similar C #Csharpthread. This article focuses on the CCSharpthread model because it is not only a type of security, but also a public non-static class method for any prototype DWORD () as a thread method. The thread method in this article refers to a function of implementing thread application logic. In C can be either a full function, or a class member method.

1. Comparison of Java, C # thread model analysis

Java, C # provides an object-oriented thread model. They all abstract thread objects, while developers implement thread application logic in a member of some classes. The development of thread application logic is simplified by separating thread objects and thread methods.

There are two ways to develop threads in Java. The first method is to derive a thread class in Thread, implement the RUN method, and call the thread.start method to start the thread, such as:

Class Mythread Extends Thread {// Create a thread class

Public void Run () {...} // thread method

}

Mythread Athread = new mythread (); // Create a thread object

Athread.Start (); // Start thread

The second method is to create a executable class by implementing the Runable interface, and use a Thread object to start the thread, such as:

Class MyRunable Implements Runnable {

Public void Run () {...} // thread method

}

Myrunable arunable = new myrunable (); // Create an executable object

Thread Athread = New Thread (arunable); // Create a thread object and associate with the executable object

Athread.Start (); // Start thread

The thread model of the C # separates the thread object and the thread method more thoroughly, it can use any prototype to void () a public class member method (static or non-static) as a thread method; the thread is also specified for a thread when the thread is started. The object of the method (the object provides various information required for thread application logic). Here is a simple example: use system;

Using system.threading;

Public class threadwork {// threadwork does not explicitly inherit any class, DOWORK can act as a thread method

Public void doork () {for (int i = 0; i <10; i ) Console.Writeline ("Working Thread ...");} // end of demork

} // end of threadwork

Class threadtest {

Public static void main () {// Execute the DOWORK method of the object ATHREAD as a thread method

ThreadWork Athread = new threadwork ();

ThreadStart mythreadDelegate = new threadstart (athread.dowork); // Specify thread method

Thread mythread = new thread (mythreaddelegate); // Create a thread object

mythread.start (); // Start thread

} // end of

Main

} // end of threadtest

The developer is most concerned about how to implement a thread method. The Java thread model provides two ways to implement thread methods, overloading Runable.Run methods, or overloading Thread.Run methods. Developers can choose the appropriate base class (Runable or Thread) based on specific applications, which is an advantage of the Java thread model. It is also possible to see that a thread method (ie, RUN method) can only be implemented in the subclass of Runable or Thread, and each subclass can only implement a thread method. The C # thread model is actually allowed in any class (not requiring this class to be a subclass of some classes (not required to be a subclass of a certain class). The thread method is implemented, and multiple thread methods can be implemented in the same class. So we think that C # thread model is more flexible, and this flexibility enables developers to make program structures more clear and reasonable.

C does not directly provide an object-oriented thread model. This article will achieve a lightweight thread model CJTHREAD / IRUNABLE similar to Java in C in C , and use templates and operator -> * to implement similar CCSharpthread. For the sake of simplicity, only the implementation of Win32 is given, and the results given by the code are the characteristics of the highlighted thread model, ignore the error check, completeness, etc. All the code in this article compiles and commissioned in VC 6.0.

2. CJTHREAD / IRUNABLE thread model

CJTHREAD / IRUNABLE is a thread model similar to Java. First define the Irunable interface, which contain the thread method RUN. CJTHREAD is then derived from Irunable. CJThread implements an empty RUN method and implements thread-related logic (creation, starting thread, etc.). The CJTHREAD object can be associated with an Irunable object, or it may not be associated. When the thread is started, if the thread object is associated with an Irunable object runobj, the line-up body CJTHREAD :: ThreadBody will hand over the control to runobj-> run; otherwise the line CJTHREAD:: ThreadBody will hand over the RUN method. Users can derive them directly by CJTHREAD and overload the RUN method to implement thread methods, or the thread method can be implemented by implementing interface Irunable (this is similar to Java). Class cjthread; //

Class Irunable {// Execute Interface

protected:

Virtual DWORD RUN () = 0; // Thread method, realized by subclass

Friend class cjthread; // allows CJTHREAD to call the RUN method, but others are not allowed to call from outside

}

Class CJTHREAD: PUBLIC IRUNABLE {// Thread class

Irunable * m_runobj; // thread correlation execution object

Handle M_HTHREAD; / / Thread Handle

Static DWORD WINAPI ThreadBody (LPVOID Param) {

CJTHREAD * PTHIS = (CJTHREAD *) Param;

Irunable * runobj = pthis-> m_runobj? Pthis-> m_runobj: pthis; / / Determine Irunable object

RETURN Runobj -> run (); // Give thread control to Irunable.run

}

protected:

DWORD RUN () {RETURN 0;} // Implement thread method so that CJThread

PUBLIC:

CJTHREAD (IRUNABLE * RUNOBJ = NULL): m_runobj (runobj) {}; // Constructor assigns M_Runobj

Bool start () {// Create a thread and start. Here is ignored, such as threads have been started.

M_Hthread = CreateThread (Null, 0, CJThread :: Threadbody, (LPVOID) this, 0, null;

Return null! = m_hthread;

}

Void Join () {waitforsingleObject (m_hthread, infinite);} // Waiting for thread to exit

}

3. CCSharpthread thread model

Implementing the CCSharpthread thread model requires Templates and Operators Operator -> *. If the reader feels unfamiliar with Operator -> *, you can refer to "Programmer" magazine 2001 No. 9 76 "Operator -> *" for smart pointers, which is very good for Operator -> *. instruction of. CCSharpthread is based on CJTHREAD / IRUNABLE, below is the implementation of CCSharpthread:

Template

Class CCSharpthread: Public CJTHREAD {

Typedef DWORD (); threadfunc threadbody; // thread method, is a non-static member method for a prototype of the template parameter class.

/ / Which method can be specified at runtime

T * m_theadfuncobj; // Provide objects for thread methods

protected:

Virtual dword run () {return (m_theadfuncobj -> * threadbody) ();} // overload thread method

PUBLIC:

CCSharpthread (T & Obj, Threadfunc_threadfunc): m_theadfuncobj (& obj), threadbody (_threadfunc) {}

}

CCSharpthread is actually a thread template that uses CCSharpthread to specify a public non-static class member method for DWORD () as a thread method (you can also modify this prototype). Constructing thread objects require two parameters, one is the thread method object OBJ, one is a thread method _threadfunc; the truly thread method of running is Obj. _Threadfunc (). Therefore, CCSharpthread is essentially a specified method of the specified object as a thread method, which is a very useful concept.

4. Example

Now use an example to demonstrate the use of two thread models of CJTHREAD / IRUNABLE, CCSharpthread, and consider the power of the ccsharpthread model. Assuming in an application, you need to start two threads, one thread adds a variable from 0 to 3 each time 1 to 3, then exits, another thread monitors this variable, and exit when this variable is 3. This application is implemented with CJTHREAD / IRUNABLE, CCSharpthread, below.

Example 1, CJTHREAD / IRUNABLE VERSION:

INT counter = 0;

Class jappthread: public cjthread {

protected:

Virtual dword run () {

For (; counter <3; counter )

{COUT << "JAPTHREAD: Counter plus 1, current value is counter =" << counter << Endl; SLEEP (1000);

Return 0;

}

}

Class Jrunable: Public Irunable {

protected:

Virtual dword run () {

While (counter <3) {cout << "JRunable: Check if the counter is 3" << endl; SLEEP (500);

COUT << "JRunable detected the counter reached 3, exiting" << endl;

Return 0;

}

}

Void jthread_test () {

Jrunable Runobj;

CJTHREAD Thread1 (& Runobj);

JAPPTHREAD THREAD2;

Thread1.start (); // Start thread

Thread2.start (); // Start thread

Thread1.join (); // Waiting for thread to exit

Thread2.join (); // Waiting for the thread to exit

}

Example 2, CCSharpthread Version:

Class app2 {

Int_Counter;

PUBLIC:

APP2 () {_counter = 0;

DWORD thREAD1 () {

While (_COUNTER <3) {cout << "thread1: Check the counter to 3" << Endl; Sleep (500);

Cout << "Thread1 detected the counter to reach 3, exiting" << endl;

Return 0;

}

DWORD thREAD2 () {

For (; _COUNTER <3; _COUNTER ) {

Cout << "Thread2: Counter plus 1, the current value is counter =" << _Counter << Endl;

Sleep (1000);

}

Return 0;

}

}

Void csharpthreadtest () {

App2 AppObj;

CCSharpthread thread1 (appobj, app2 :: threeread1);

CCSharpthread thread2 (appobj, app2 :: thread2);

Thread1.start (); // Start thread

Thread2.start (); // Start thread

Thread1.join (); // Waiting for thread to exit

Thread2.join (); // Waiting for the thread to exit

}

The two examples of the contrast can be found that two classes are defined in Example 1, defined two classes; in order for these two classes to access counter Counter, we define the counters as global variables. Example 2 Only one class app2 is defined, and two thread methods are implemented; while simultaneous examples 2 define the counter _Counter as the private variable of the app2. Obviously, regardless of the simplicity of the program or from the rationality of the program structure, Example 2 is better than Example 1. In addition, since the two nonstatic member methods of App2 are used as a thread method, the _counter is defined as static variables as the traditional method. In other words, the two threads in Example 2 realize the object-level sharing information, which is a very useful feature of CCSharpthread, which makes it clearer, reasonable, and reasonable use of this feature developer.

5. Type security

CJTHREAD / IRUNABLE model Type security is now associated with CJTHREAD only with an Irunable object (objects that implement the Irunable interface). Due to the use of templates, the CCSharpthread model is a real type of security, such as compiling the following code:

Class app3 {

PUBLIC:

DWORD INVALIDTHREADBODY () {Return 0;}

}

App2 AppObj;

CCSharpthread thread (appobj, app3 :: invalidthreadbody); // Attempt to call AppObj-> InvalidThreadBody method

A compile error error C2664: '__thiscall CCSharpThread :: CCSharpThread (class App2 &, unsigned long (__thiscall App2 :: *) (void))': can not convert parameter 2 from 'unsigne d long ( __thiscall cop3 :: *) (void) 'to' unsigned long (__thiscall app2 :: *) (void) '. This prevents developers from using App2 objects to call the APP3 member method. 6. Summary

This article achieves the CJTHREAD / IRUNABLE model by encapsulating the C interface API and further establishes a CCSharpthread model. It can be seen that the implementation of these two models is very simple, and the requirements for resources are also very low, which means they are very efficient, which makes them a very good choice for lightweight C multi-threaded applications. In fact, it should be pointed out that CCSharpthread's "public non-statically non-static member method that will meet any prototype is as a thread method", as well as the characteristics of its type, so that it is more powerful than the thread model provided by the MFC, VCL, etc. .

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

New Post(0)