Processing mechanism based on multi-task synchronization based on Sockets

zhaozj2021-02-16  94

table of Contents

Summary

Scenes and issues of multitasking synchronization

Use the commissioned synchronization solution

Program with thread synchronization

Discussion on several problems of two programs

Summary:

Based on Sockets-based network programming, since sockets's communication mechanisms are round-trip messaging mechanisms, the completion of a single task is made (each step can also be referred to as a small task), depending on or depends on the preamble The task, so asynchronousness of programming processing is reflected. These mutually coherent or associated tasks can be implemented in accordance with a predetermined definition process, and a key issue is how to synchronize. What kind of synchronization mechanism is essentially used to coordinate multiple tasks, of course, any mechanism is not suitable for any occasion, and the key is to see demand. This article will give some basic concepts and scenes, problems, and then propose to achieve synchronization, and make discussions, pointing out that there is problems and applicable.

Scenes and issues of more than 1 task synchronization

1.1 Some concepts involved in multitasking

Task: Logically completes a collection of steps or more operations, this concept is very general, in principle, there is no strict requirements to define it, need readers to understand.

Current task: The task being executed;

Guide Task: The current task must be completed before the start. This is actually a front-rear relationship, not only after the preamble task is completed, and the logic of how the current task is done depends on the status of the task preamble task.

Subsequent task: The task that is started after the current task is completed. The current task is the successive task of the preamble task.

1.2 a scene of multitasking and the problems

In a project involved in the author, there is such a requirement for distributed file storage services:

In this system, there are multiple clients and a server, each client contributes a certain disk space to form part of the virtual disk on the network, so the specific file data is stored on the client, and the server only stores about the file Information, such as the directory information, information of the file (file name, size, owner, file distribution). Therefore, the physical storage location of the user uploaded to the system is actually distributed on several clients (one block of each client). Then use the user request to download the file, you need to download all the blocks from all the blocks that store the file, and then merge into the original file. If the file currently has a file name A.rar is split into 3 parts (split into a.rar.1, a.rar.2, a.rar.3) is stored in different machines (x, y, Z). Now there is a machine H now want to download A.rar files, then it will actually get A.rar.1 from the X machine, then get A.rar.2 from the Y machine, and finally get A.rar from the z machine. .3 then incorporated into a.rar, can be represented by the flow chart

These three transmission can be called a task, and this task contains three subtasks, and these three sub-tasks are executed, assuming that the current task is to transfer A.rar.2 files with Y, If the task is executed, it must be the premise of success in the forward task (and X transmission a.rar.1 file), of course, if the current task is executed, then the subsequent task (and z transmission a.rar.3 file) It must not start. Obviously, there is a synchronous problem between these three tasks.

2. Use the commissioned synchronization solution

When the author encountered the above problems during the design process, the author thought of using the entrusted to synchronize these three tasks, that is, in the current task, the X-machine transmission A.rar.1 is completed, through the entrusted callback, the successful task is also The Y machine transmits A.rar.2 task. First give a file transfer function: public void readfiledata (System.Net.Sockets.Socket Sock, String FileName, Long FileSize, MessageEventhandler DownloadFileCall)

{

FILESTREAM Fout = New FileStream (FileName, Filemode.create, FileAccess.write);

/ / Read file stream according to the file name

NetworkStream NFS = New NetworkStream (SOCK);

// Bind the network to a specific socket

Long size = filesize;

Long rby = 0;

Try

{

While (RBY

// Use the length of the determination to transmit the entire length of the length.

{

Byte [] buffer = new byte [32767];

INT i = 0;

Try

{

I = NFS.Read (buffer, 0, buffer.length);

// read the specific length of the file stream into the cache.

}

Catch (Exception E)

{

String temp = e.tostring ();

}

Fout.write (buffer, 0, (int) i);

// Write the cache to the network stream

RBY = RBY I;

ShowProgress (filename "|" (RBY * 100 / size));

Thread.sleep (100);

}

NFS.Flush ();

NFS.Close ();

NFS = NULL;

Fout.flush ();

Fout.close ();

DownloadFileCall ("Downloadfileok");

/ / The following tasks are performed by callback.

Return;

}

// abnormal processing

Catch (Exception ED)

{

Fout.flush ();

Fout.close ();

THIS.VIEWMESSAGE ("a Exception Occured In File Transfer" Ed.Tostring ());

}

}

It can be seen that there is a delegate parameter DownloadFileCall in the parameter table of this function, and it can be seen when the entire file is complete. Let's take another look at how this function is called and what function is that the delegate callback:

Private void Downsinglefile (String State)

{

IF (hustfile! = null)

{

Hustfile.dispose ();

Hustfile = NULL;

}

SplitefileInfo currentfile = (splitefileinfo) Down_filelist [fileIndex];

Hustfile = New FileSocket (Currentfile.LocationIP, CurrentFile.userport, New Callback (this.viewMessage), New Callback (this.viewProcess);

Hustfile.Connect ();

Thread.sleep (1000);

IF (this.fileIndex

{

FileIndex ; hustfile.getfile (currentfile.filename, currentfile.size, new callback (this.downsinglefile);

}

// The last file should be recovered after it is completed.

Else

{

Hustfile.getfile (currentfile.filename, currentfile.size, new callback (this.recoverfile);

}

}

Public void getfile (String FileName, Long FileSize, Callback FiledownOver)

{

Socket Sock = Client_socket;

IF (Sock! = NULL)

{

WRITELOG ("Request Download File");

this.Downloadfile = filedownover;

String cmd = "getfile:";

String msg = cmd filename;

THIS.FILENAME = filename;

THIS.FILESIZE = FileSize;

Sender = system.text.Encoding.ascii.getbytes (msg);

Sock.send (Sender);

WriteLog ("File Download Start");

(New FileTransfer (ShowProcess)). ReadFileData (Sock, FileName, FileSize, Downloadfile;

}

}

We can pay attention to the IF-ELSE statement in the DOWNSINGLEFILE. When the judgment condition is established, it is called the getFile function, and the DOWNSINGLEFILE function itself is incorporated into getFile as the callback function, and in the getFile function, it will incur. The delegate passed directly to the ReadFileData functionality given. This means that when the two tasks are in front, ReadFileData is turned to DownsingleFile when the task is completed, and the next transfer task is executed. At the same time, we can see when arriving at A.rar.2 transfer, callback DOWNSINGLEFILE will execute the statement in Else to get GetFile, then pass the callback function transmitted to the ReadFileData by getFile will no longer Downsinglefile is one. Called with Recovefile, it is obvious that after all of our transfer tasks are completed, the next step will be the merging this file.

When the author solves the coordination of the three sub-tasks, the author is handed over to the preamble task if the decision of the current task is executed, and it is implemented by delegate the callback. The next task is executed after the current guide task is completed. Of course, the same is the decision of the subsequent task handed over the current task. The successful post-callback task is called only if the current task is completed.

3. Program with thread synchronization

When encountering the above problem, it is of course also possible to use thread synchronization methods. Let's take a look at the picture below:

The main thread function sequence and X, Y, Z transmit the corresponding file, and after the file transfer thread is activated, the main thread is implied. The listening thread is the command transmission between the two hosts. When the monitor thread receives the message sent by the other party, the main thread will continue to execute, and its function is implemented here. I use pseudo code as follows. :

Main thread:

First, you want to define an object m_sync for thread synchronization.

Private manualReveTevent m_sync = new manualRetevent (false);

Next is the code responsible for file transfer in the main thread.

MAINTHREAD ()

{

FileName = .........; // Get the file name that needs to be transmitted.

Filesocket = .........; // Generate and X Transmission socket. (New fileTransfer) .Transfer (filesocket, filename, ...); // and X machine transfer files

m_sync.waitone ();

FileName = .........; // Get the file name that needs to be transmitted.

FileSocket = .........; // Generate and Y transmission socket.

(New FileTransfer) .Transfer (FileSocket, filename, ...); // and Y machine transfer files

m_sync.waitone ();

FileName = .........; // Get the file name that needs to be transmitted.

FileSocket = .........; // Generate and Z Transport sockets.

(New fileTransfer) .Transfer (FileSocket, filename, ...); // and z machine transfer files

Recoverfile (); // Restore the entire file

}

Let's pay attention to how to wake up the main thread of the blocking thread.

Because the author is designing the entire system, there is a special listening thread has been responsible for communication at both ends. After the thread receives the command to complete the other party file, it will call a m_sync.set () to wake up the blocked master Thread. This allows the main thread to continue the next task. The above methods can also be synchronized between multiple tasks.

4. Discussion on several problems of two programs

Our two methods we have taken are the solution taken when we do in advance to perform the execution of three subtasks as serial. And when we solve this problem, is the only or optimal solution using serial transmission. The answer is obviously not necessarily, we can also use parallel processing methods, which is three transfer file tasks, we can choose concurrent, so when the three transfer processes do not have problems, it is obviously more than the serial way we use. Excellent, but when you meet online problems or other questions, our transmission is unsuccessful, then theoretically, the other two transmission will not continue to perform. That is to say, there is a multi-task synchronization problem, this problem will not be discussed here.

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

New Post(0)