Document directory
- Server Object
- Serverloader
- Simpleclient
- Digits of PI Client
- Thread Synchronization
- Summary
- Other resources
. Net remoting allows you to easily perform distributed computing across multiple computers, with only a few programming tasks required. In this article, Eric Bergman-Terrell created an application named digits of Pi, which uses parallel computers to calculate P values with incredible precision. He managed to complete 10,000-digit computing within 12 hours, but only used a small amount of computing resources. This is 300% faster than a single computer.
. Net remoting allows objects to communicate with other objects, whether they run on the same computer or on a remote computer ..
To access a remote object, follow these steps:
- Create a. NET Server Object (DLL) inherited from system. externalbyrefobject ). The server object will run on the remote computer and local computer.
- Create a server loader program that calls remotingconfiguration. Configure to load server objects. The server loader program will also run on the remote computer and local computer.
- Create a client program that uses activator. GetObject to access the server object. You need to add a reference to the server object to compile this program. This client program runs only on the local computer.
Server Object
The server object calculates the specified nine-bit P value. It is named plouffe_bellard because it uses the enhanced Simon Plouffe algorithm of Fabrice bellard. Although there is a faster algorithm, the Plouffe-bellard algorithm is very simple (less than 300 lines of source code), it uses a small amount of memory, and because nine digits can be calculated separately, therefore, it is more suitable for parallel execution. The plouffe_bellard.calculatepidigits method calculates the Nine-bit P value starting from the specified position. For example, calculatepidigits (1) returns nine digits starting from the first digit: 141592653. Calculatepidigits (10) returns nine digits starting from the tenth digit, and so on.
Serverloader
The serverloader program loads the Server Object, specifies the protocol and port for accessing the server object through the LAN, listens for incoming calls from the client program, processes the call, and returns the result. It is particularly worth noting that all of this can be done with only one line of code. You only need to call the remotingconfiguration. Configure method by using the path of the configuration file. The serverloader program loads the configuration file named serverloader.exe. config (see table 1 ). This configuration file is used to load server objects in singlecall mode. That is, each incoming call is processed by a new instance of the server object. If the server object is loaded in singleton mode, each incoming call is processed by the same instance. Type attribute specifies the name of the complete type of the server object (including the Pb namespace) and its assembly. The objecturi attribute specifies the endpoint of the object's Uniform Resource Identifier (URI. <Channel> the element specifies that the TCP protocol is used and port 9000 is used to access the server object.
Table 1: serverloader.exe. config.
<configuration> <system.runtime.remoting> <application name = "ServerLoader"> <service> <wellknown mode="SingleCall" type="PB.Plouffe_Bellard,Plouffe_Bellard" objectUri="Plouffe_Bellard"/> </service> <channels> <channel ref="tcp server" port="9000"/> </channels> </application> </system.runtime.remoting></configuration>
Simpleclient
I created a program named simpleclient to demonstrate how easy it is for a client program to access a server object on a remote computer. To run simpleclient, run serverloader on a remote computer, and then run simpleclient.exe on a local computer. Enter the name of the remote machine in the remote machine text box, and then click the calculate button to calculate the first nine-bit P value. The calculatebutton_click method of simpleclient contains all the code required by the client to access the remote server (see table 2 ). You can use a URL consisting of the remote computer name, protocol (TCP), and port number (9000) to access the remote server. For example, to access my "Pentium 200" computer, the URL is TCP: // Pentium 200: 9000/serverloader/plouffe_bellard. After a URL is created, activator. GetObject is called using the server type (plouffe_bellard) and URL. Then, the returned value is converted to the plouffe_bellard object for use. When the calculatepidigits method is called, the request is sent to the serverloader on the remote computer. Then, the server object calculates the decimal point. Finally, the result of the returned client program is displayed in a text box.
Table 2: simpleclient code used to access the remote server.
Private void calculatebutton_click (Object sender, system. eventargs e) {cursor. current = cursors. waitcursor; plouffe_bellard picalculator = NULL; string machinename = remotemachinetextbox. text; try {int Port = 9000; string url = "TCP: //" + machinename + ":" + port + "/serverloader/plouffe_bellard"; picalculator = (plouffe_bellard) activator. getObject (typeof (plouffe_bellard), URL); resultstextbox. TEXT = "3. "+ picalculator. calculatepidigits (1);} catch (exception) {MessageBox. show ("need to run serverloader.exe", messageboxbuttons on computer "+ machinename," simple client. OK, messageboxicon. error);} cursor. current = cursors. arrow ;}
Digits of PI Client
The digits of PI client program is more complex than simpleclient. Simpleclient only calculates the first nine P values by accessing the server objects on the remote computer. Digits of PI uses the remote computer and local computer (1) specified in the configure (configuration) dialog box to concurrently calculate the user-specified decimal places. The server object is accessed in a separate thread to maintain the responsiveness of the digits of pi gui to user operations during a long computing process.
Digits of PI uses arrays to divide jobs into nine-bit data blocks and allocate the workload to all available computers. After you click the calculate button, the solutionarray is created (see figure 4 ). Solutionarray assigns a solutionitem element to each group of nine P Values to be calculated. After the Nine-Bit Array specified by the m_digit field is calculated on the server object, the digits are stored in the m_results member. The m_machinename member contains the name of the computer on which the server is running. The storage computer name is used to enable digits of PI to display the total number of decimal points calculated by each computer (see figure 2 ).
To enable parallel computing of server objects, digits of PI creates a thread for each server object and starts thread computing. Then, the final result can be displayed only after all threads have completed computation. Waithandle is useful for waiting for multiple threads. Digits of Pi will use a waithandle for each thread to wait for all threads to complete the computation.
Calculationthread. Calculate (see table 3) is called to create a thread for each server object. This operation starts the thread and returns an autoresetevent (derived from waithandle ). The autoresetevent of each thread is stored in an array, and the array is passed to waithandle. waitall. After the thread computing is completed, the set method is called for its autoresetevent. After the last thread calls the set method, it returns the waitall call and displays the value of P.
Table 3: calculationthread.
public static WaitHandle Calculate(SolutionArray solutionArray, String machineName){ CalculationThread calculationThread = new CalculationThread(solutionArray, machineName); Thread thread = new Thread(new ThreadStart(calculationThread.Calculate)); thread.Start(); return calculationThread.calculationDone;}
Each thread uses the same algorithm: if more work is required, the thread will capture the next solutionitem, store the computer name of the server object in solutionitem, and calculate the specified nine decimal places, and store the results in solutionitem. This process will run until all solutionitems are filled with results. For more information, see table 4.
Table 4: calculationthread. Calculate.
Public void calculate () {plouffe_bellard picalculator = remotepicalculator. getpicalculator (getrealmachinename (machinename); If (picalculator! = NULL) {solutionitem item = NULL; bool abort; do {abort = solutionarray. Abort; If (! Abort) {item = solutionarray. getnextitem (); If (item! = NULL) {item. machinename = machinename; try {item. results = picalculator. calculatepidigits (item. DIGIT);} catch (exception e) {abort = true; MessageBox. show ("remote objects cannot be accessed on the host" + machinename + environment. newline + environment. newline + "message:" + E. message, globals. programname, messageboxbuttons. OK, messageboxicon. error);} updatestatisticsdelegate USD = new updatestatisticsdelegate (MF. update Statistics); Mf. Invoke (USD, new object [] {}) ;}} while (item! = NULL &&! Abort); calculationdone. Set ();}}
The following is a step-by-step description:
- Getrealmachinename removes the @ 1 mode from the names of multiple CPU computers. For example, getrealmachinename ("brainiac @ 1") returns "Brainiac ". For more information about the names of multiple CPU computers, see the text in Figure 1.
- After knowing the correct computer name, pass it to remotepicalculator. getpicalculator to access the server objects on the computer through the picalculator variable.
- If you click the cancel button, the abort attribute is set. If the abort attribute is true, the thread stops computing.
- The mf. Invoke call allows the thread to securely update the statistics in the listview (see figure 2), even if the listview is created by another thread. In 32-bit windows programming, the control cannot be processed outside the thread where a control is created.
- The Set function of the autoresetevent of the thread is called after the loop is completed (that is, after all the specified p-bits are calculated or you click the cancel [cancel] button.
- After each thread calls the set function of its autoresetevent, the call to waithandle. waitall is returned and the result is displayed.
Thread Synchronization
If the digits of pi code is accessed by multiple threads at the same time, an error may occur in multiple places. For example, if two threads call solutionarray. getnextitem at the same time, the same content may be returned. This is why the [methodimpl (methodimploptions. Synchronized)] attribute is set in the getnextitem method. This attribute ensures that only one thread calls this method at a time. If each line of code of a method should not be accessed by multiple threads at the same time, it is a good policy to synchronize methods.
Because the mainform. Calculate Method has only one line of code that cannot be accessed by multiple threads at the same time, it will call monitor. Enter before the line of code and then call monitor. Exit. If this line of code is already running on another thread, monitor. Enter will be blocked. If the entire function has been synchronized, only the code lines that need to be accessed by multiple threads can be protected to improve performance.
Objects derived from system. Windows. Forms. Control (such as button, textboxe, richtextboxe, label, listboxe, and listview) should only be processed by the thread that created them. To safely Process Control-derived objects from non-creation threads, first put the processing code into a method, and then declare a proxy for the method:
delegate void SetResultsTextDelegate(String Text);private void SetResultsText(String Text){ ResultsRichTextBox.Text = Text;}
Then, use form. invoke to call this method indirectly:
SetResultsTextDelegate SRTD = new SetResultsTextDelegate(SetResultsText);Invoke(SRTD, new object[] { "" } );
The invoke method calls this method from the thread where it is created. The parameters used by the invoke method correspond to the elements in the object array.
Summary
. Net remoting is a simple and effective mechanism for executing code on remote (and local) computers. You only need to encapsulate the code into a. Net object, write a program that loads the object and listens to the request, and then call activator. GetObject in the client program. If your lan has idle computers, you can use them to easily solve parallel problems. Remember to use the correct thread synchronization mechanism to prevent conflicts between threads.
DownloadTerrell. Zip
Other resources
- "ASP. NET web service or. NET remoting: How to choose" (http://www.microsoft.com/china/msdn/library/dnbda/html/bdadotnetarch16.asp) is useful in comparing. NET web service and. Net remoting.
- Fabrice bellard's pi page (http://fabrice.bellard.free.fr/pi/) provides some useful formulas and source code for calculating the P value, including the C-language source code of the Algorithm Used in the digits of PI program.
- For the source code of the Remote Access Program, visit www.personalmicrocosms.com/html/ra.html. This program uses. Net remoting to display the desktop of the remote computer and runs the remote computer with the keyboard and mouse of the local computer.
- For more information about mathematics, see the history of PI (St. martin's Press was published in 1971). This is a pretty good book, because P's history is a microscopic reflection of the history of mathematics. Beckmann's book covers P's mathematical and political history.
- Advanced. Net remoting (published by apress in 2002) by Ingo Rammer is an authoritative guide on remoting. This book seems more suitable for detailed reading from start to end. I hope this book will be suitable for my reading habits of "turning over at will.
For more information about hardcore Visual Studio. NET and pinnacle Hing, visit their Web site http://www.pinpub.com /.
Note: This is not a web site of Microsoft Corporation. Microsoft is not liable for the content of the site.
This article is reproduced from hardcore Visual Studio. NET in July. Copyright: 2003 pinnacle Publishing, Inc. (unless otherwise stated ). All rights reserved. Hardcore Visual Studio. NET is an independent publication of pinnacle Hing, Inc. No part of this article shall be used or reproduced in any form without the prior consent of pinnacle Publishing, Inc. (except for short references in comments ). To contact pinnacle Hing, inc., call 1-800-788-1900.