I would like to know:
If a make two consecutive MPI_Isend requests, and if the destination processor has not yet receive the message inbetween the two calls, will the buffer be updated ?
I mean if I send message "0" for the first request, then send "1" as the second message. Will the receiver receive "0" as message ? I not, how can I do to update the message ?
Thanks
double message;
int i = 0;
//First processor
if (rank == 0)
{
for (i = 0; i < 2; i++)
{
message = i;
MPI_Isend(&message, 1, MPI_DOUBLE, 1, 0, PETSC_COMM_WORLD, r_send);
}
}
//Second processor
if (rank == 1)
{
PetscSleep(10); // Make this processor sleep for 10 seconds
int flag = 0;
MPI_Irecv(&message, 1, MPI_DOUBLE, 0, 0, PETSC_COMM_WORLD, r_recv);
MPI_Test(r_recv,&flag, r_status);
while (!flag)
{
MPI_Test(r_recv,&flag, r_status);
}
printf("the message is %lf\n",message);
}
This code above will print "the message is 0". I want it to take into account the last update, not the first in-order messages.
MPI messages are "non-overtaking", meaning that the first message sent will be received first. So when you post your Irecv, that first message will be received. 2. I don't think the tests after the receive do anything useful. If your test says there is a message, you need a new receive to get it. 3. Why are you using a "ready" send? 4. Neither of your processes is doing a Wait call, so it could be that this whole program is Undefined Behavior.
Related
Ive incorporated multiple features i want in a microcontroller program (ESP32 Wroom32) and needed some advice on the best way to keep the program running and receive messages while it is running.
Current code:
//includes and declarations
setup()
{
//setup up wifi, server
}
main(){
WiFiClient client = server.available();
byte new_command[40];
if (client) // If client object is created, a connection is setup
{
Serial.println("New wifi Client.");
String currentLine = ""; //Used to print messages
while (client.connected())
{
recv_byte = client.read();
new_command = read_incoming(&recv_byte, client); //Returns received command and check for format. If invalid, returns a 0 array
if (new_command[0] != 0) //Checks if message is not zero, None of valid messages start with zero
{
execute_command(new_command);
//new_command is set to zero
}
}//end of while loop
}//end of if loop
}
The downside of this is that the ESP32 waits till the command is finished executing before it is ready to receive a new message. It is desired that the ESP32 receive commands and store them, and execute it at its own pace. I am planning to change the current code to receive a messages while the code is running as follows:
main()
{
WiFiClient client = server.available();
byte new_command[40];
int command_count = 0;
byte command_array[50][40];
if (command_count != 0)
{
execute_command(command_array[0]);
//Decrement command_count
//Shift all commands in command_array by 1 row above
//Set last executed command to zero
}
}//end of main loop
def message_interrupt(int recv_byte, WiFiClient& running_client)
{
If (running_client.connected())
{
recv_byte = running_client.read();
new_command = read_incoming(&recv_byte, running_client); //Returns received command and check for format. If invalid, returns a 0 array
//add new command to command_array after last command
//increment command_count
}
}
Which interrupt do I use to receive the message and update the command_array ? https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html Doesnt mention any receive/transmit events. I couldnt find any receive/transmit interrupt either or maybe I searched for the wrong term.
I'm writing a Class for COM ports in C++ using win-api. Righ now I test the functionality on RS232 with connected Rx and Tx pins.
I've encountered somewhat weird problem. I use separate thread for reading from the COM port. Within the thread I use SetCommMask, WaitCommEvent and WaitForSingleObject to wait for char arrival into buffer. However the WaitForSingleObject tends to exit without actually receiving any chars.
I assumed this was caused by wrong use of mentioned functions, but then I discovered, that premature exit does not occur every time (first time always works as intended).
In second go the thread enters the waiting state and exits a while later proceeding to ReadFile, where it waits indefinitely, because the buffer is empty, no data is to be sent and Total timeout is not used.
I've already been advised to simply use ReadFile and process only the data I acquire, however I use another thread to check if the communication channel has been disconnected and right now I need to distinguish between waiting for data and reading data.
Calling ClearCommError to check input buffer with ReadFile is not an option, because in such a case InQue is always 0. Therefore I cannot tell whether ReadFile is actually reading or waiting.
//following code runs in separate thread
DWORD dwEventMask1, dwEventMask2, LastError, Status;
OVERLAPPED Overlapped; HANDLE Serial_Port_Handle;
std::string stringBuffer("");
const size_t ReadBufferLength = 256;
char tempBuffer[ReadBufferLength];
GetCommMask(Serial_Port_Handle, &dwEventMask1);
if (dwEventMask1) // Before starting the thread I check the state of Input Buffer with GetCommError().
{ // If Buffer is not empty, CommMask is set to 0 signaling there is no need for waiting.
Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//wait for comm event
if (!WaitCommEvent(Serial_Port_Handle, &dwEventMask1, &Overlapped))
{
if ((LastError = GetLastError()) == ERROR_IO_PENDING)
{
Waiting = true; //signal bool for synchronization purposes
if ((Status = WaitForSingleObject(Overlapped.hEvent, INFINITE)) == WAIT_OBJECT_0)
{
GetCommMask(Serial_Port_Handle, &dwEventMask2);
Waiting = false;
CloseHandle(Overlapped.hEvent);
// I close handle and set all members of Overlapped struct to 0
}
if (dwEventMask2 !== dwEventMask1) // check if wait have not exited because of SetCommMast()
return;
}
}
}
do // this loop reads from input buffer until empty
{
Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//set up read overlapped operation
if (ReadFile(Serial_Port_Handle, tempBuffer, ReadBufferLength - 1, &NoBytesRead, &Overlapped)) //start read opperation
{ //Read operation done on 1 go
GetOverlappedResult(Serial_Port_Handle, &Overlapped, &NoBytesRead, FALSE); //get NoBytesRead
CloseHandle(Overlapped.hEvent)
stringBuffer.append(tempBuffer, (size_t) NoBytesRead); // save read data
}
else if ((LastError = GetLastError()) == ERROR_IO_PENDING) //operation not yet complete
{
GetOverlappedResult(Serial_Port_Handle, &Overlapped, &NoBytesRead, TRUE); // wait for completion
stringBuffer.append(tempBuffer, (size_t)NoBytesRead);
}
else
{
CloseHandle(Overlapped.hEvent)
return;
}
} while ((NoBytesRead == (ReadBufferLength - 1)) && NoBytesRead);
// Loop runs while tempBuffer's full capacity is used.
// I realize that since I don't use Total Timeout there is a possibility
// of the loop getting stuck. If you can suggest other solution than using
// Total Timeout or use GetCommError() to get input buffer state, please do so.
return;
This code is somewhat simplified (checking for return values, ets.).
1) Have any of you experienced such a behaviour?
2) I use OVERLAPPED operations in the code. After the operation exits I always use CloseHandle and reinitialize the OVERLAPPED structure before using it for another operation. Is this correct or is resetting the structure sufficient?
It is bad logic as a whole. For example, there are the following issues.
CreateEvent/CloseHandle should not executed at every ReadFile/WaitCommEvent.
The usage of GetCommMask/WaitCommEvent is also wrong.
The read data size specified in ReadFile is fixed regardless of the situation.
It also includes the comment on #RbMm.
You may want to redesign your program with reference to the following articles and source code:
Synchronization and Overlapped Input and Output
Serial Communications
bmo/mttty
In Addition:
I did not notice that a file handle (not an event handle) was specified for WaitForSingleObject, as pointed out by #Rita Han.
The biggest problem is that.
However, the situation that it is better to redesign has not changed.
There is no description of WaitCommEvent and Overlapped for it in the source of #Rita Han's answer. Also, the read data size is fixed in ReadFile.
On the other hand:
Although it does not occur in the source code of the question, it is possible for WaitCommEvent/WaitForSingleObject to generate an event that is not specified in SetCommMask.
While the WaitCommEvent is waiting for completion, change the event mask with SetCommMask.
Remarks - WaitCommEvent function
If a process attempts to change the device handle's event mask by using the SetCommMask function while an overlapped WaitCommEvent operation is in progress, WaitCommEvent returns immediately. The variable pointed to by the lpEvtMask parameter is set to zero.
While WaitCommEvent is waiting for completion, call WaitCommEvent multiple times using the same Overlapped structure.
Synchronization and Overlapped Input and Output
When performing multiple simultaneous overlapped operations on a single thread, the calling thread must specify an OVERLAPPED structure for each operation. Each OVERLAPPED structure must specify a handle to a different manual-reset event object.
A thread should not reuse an event with the assumption that the event will be signaled only by that thread's overlapped operation. An event is signaled on the same thread as the overlapped operation that is completing. Using the same event on multiple threads can lead to a race condition in which the event is signaled correctly for the thread whose operation completes first and prematurely for other threads using that event.
The document is described as above, but depending on the device driver/vendor, the WaitCommEvent that is called later ends with an error, and the WaitCommEvent waiting for completion is lpEvtMask return with zero (as in SetCommMask).
For multiple Overlapped structure variables:
A common programming know-how is that using a single variable for multiple purposes is prone to bugs.
If you are designing in asynchronous and/or multi-threading, it is better to prepare at least three Overlapped structure variables for ReadFile, WriteFile, WaitCommEvent.
About starting ReadFile regardless of the state of the input buffer:
This is about calling ReadFile with a fixed length of 256 bytes without acquiring the size of the received data in the input buffer of the device driver.
In fact, even if all the data arrives, if it is less than 256 bytes, it will always be delayed until a 256 byte receive timeout occurs.
For example, the loop reads one byte at a time until a timeout error occurs, which means the end of the received data (1-byte read timeout would have no impact).
Or, as answered in the previous article, use ClearCommError to obtain the size of the data stored in the device driver's input buffer, and call ReadFile specifying that size.
There will be no problem with the application-side buffer handling you are explaining.
About the behavior of WaiCommEvent when calling SetCommMask:
It may depend on the device driver you are using.
However the WaitForSingleObject tends to exit without actually
receiving any chars.
Wait for the event handle instead of serial device handle.
I got it working. The following is my code example you can have a try:
DWORD errCode = 0;
BOOL result = false;
HANDLE serialDeviceHdl = CreateFile(L"COM8", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (!serialDeviceHdl)
{
errCode = GetLastError();
cout << "Open device failed. Error code: " << errCode << endl;
return 0;
}
OVERLAPPED overlappedForWrite = {};
overlappedForWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DWORD writenSize = 0;
result = WriteFile(serialDeviceHdl, "hello", 5, &writenSize, &overlappedForWrite);
if (FALSE == result)
{
errCode = GetLastError();
if (ERROR_IO_PENDING == errCode)
{
cout << "Overlapped I/O operation is in progress." << endl;
}
else
{
cout << "Write to device failed. Error code: " << errCode << endl;
}
}
DWORD returnValue = WaitForSingleObject(overlappedForWrite.hEvent, INFINITE);
if (WAIT_OBJECT_0 == returnValue)
{
cout << "The state of the specified object is signaled." << endl;
}
else
{
cout << "Wait for single object failed. Error code: " << returnValue << endl;
}
CHAR readBuf[5];
DWORD readSize = 0;
OVERLAPPED overlappedForRead = {};
overlappedForRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
result = ReadFile(serialDeviceHdl, readBuf, 5, &readSize, &overlappedForRead);
if (FALSE == result)
{
errCode = GetLastError();
if (ERROR_IO_PENDING == errCode)
{
cout << "Overlapped I/O operation is in progress." << endl;
}
else
{
cout << "Write to device failed. Error code: " << errCode << endl;
}
}
returnValue = WaitForSingleObject(overlappedForRead.hEvent, INFINITE);
if (WAIT_OBJECT_0 == returnValue)
{
cout << "The state of the specified object is signaled." << endl;
}
else
{
cout << "Wait for single object failed. Error code: " << returnValue << endl;
}
I use MPI non-blocking communication(MPI_Irecv, MP_Isend) to monitor the slaves' idle states, the code is like bellow.
rank 0:
int dest = -1;
while( dest <= 0){
int i;
for(i=1;i<=slaves_num;i++){
printf("slave %d, now is %d \n",i,idle_node[i]);
if (idle_node[i]== 1) {
idle_node[i] = 0;
dest = i;
break;
}
}
if(dest <= 0){
MPI_Irecv(&idle_node[1],1,MPI_INT,1,MSG_IDLE,MPI_COMM_WORLD,&request);
MPI_Irecv(&idle_node[2],1,MPI_INT,2,MSG_IDLE,MPI_COMM_WORLD,&request);
MPI_Irecv(&idle_node[3],1,MPI_INT,3,MSG_IDLE,MPI_COMM_WORLD,&request);
// MPI_Wait(&request,&status);
}
usleep(100000);
}
idle_node[dest] = 0;//indicates this slave is busy now
rank 1,2,3:
while(1)
{
...//do something
MPI_Isend(&idle,1,MPI_INT,0,MSG_IDLE,MPI_COMM_WORLD,&request);
MPI_Wait(&request,&status);
}
it works, but I want it to be faster, so I delete the line:
usleep(100000);
then rank 0 goes into a dead while like this:
slave 1, now is 0
slave 2, now is 0
slave 3, now is 0
slave 1, now is 0
slave 2, now is 0
slave 3, now is 0
...
So does it indicate that when I use the MPI_Irecv, it just tells MPI I want to receive a message hereļ¼haven't received message), and MPI needs other time to receive the real data? or some reasons else?
The use of non-blocking operations has been discussed over and over again here. From the MPI specification (section Nonblocking Communication):
Similarly, a nonblocking receive start call initiates the receive operation, but does not complete it. The call can return before a message is stored into the receive buffer. A separate receive complete call is needed to complete the receive operation and verify that the data has been received into the receive buffer. With suitable hardware, the transfer of data into the receiver memory may proceed concurrently with computations done after the receive was initiated and before it completed.
(the bold text is copied verbatim from the standard; the emphasis in italic is mine)
The key sentence is the last one. The standard does not give any guarantee that a non-blocking receive operation will ever complete (or even start) unless MPI_WAIT[ALL|SOME|ANY] or MPI_TEST[ALL|SOME|ANY] was called (with MPI_TEST* setting a value of true for the completion flag).
By default Open MPI comes as a single-threaded library and without special hardware acceleration the only way to progress non-blocking operations is to either call periodically into some non-blocking calls (with the primary example of MPI_TEST*) or call into a blocking one (with the primary example being MPI_WAIT*).
Also your code leads to a nasty leak that will sooner or later result in resource exhaustion: you are calling MPI_Irecv multiple times with the same request variable, effectively overwriting its value and losing the reference to the previously started requests. Requests that are not waited upon are never freed and therefore remain in memory.
There is absolutely no need to use non-blocking operations in your case. If I understand the logic correctly, you can achieve what you want with code as simple as:
MPI_Recv(&dummy, 1, MPI_INT, MPI_ANY_SOURCE, MSG_IDLE, MPI_COMM_WORLD, &status);
idle_node[status.MPI_SOURCE] = 0;
If you'd like to process more than one worker processes at the same time, it is a bit more involving:
MPI_Request reqs[slaves_num];
int indices[slaves_num], num_completed;
for (i = 0; i < slaves_num; i++)
reqs[i] = MPI_REQUEST_NULL;
while (1)
{
// Repost all completed (or never started) receives
for (i = 1; i <= slaves_num; i++)
if (reqs[i-1] == MPI_REQUEST_NULL)
MPI_Irecv(&idle_node[i], 1, MPI_INT, i, MSG_IDLE,
MPI_COMM_WORLD, &reqs[i-1]);
MPI_Waitsome(slaves_num, reqs, &num_completed, indices, MPI_STATUSES_IGNORE);
// Examine num_completed and indices and feed the workers with data
...
}
After the call to MPI_Waitsome there will be one or more completed requests. The exact number will be in num_completed and the indices of the completed requests will be filled in the first num_completed elements of indices[]. The completed requests will be freed and the corresponding elements of reqs[] will be set to MPI_REQUEST_NULL.
Also, there appears to be a common misconception about using non-blocking operations. A non-blocking send can be matched by a blocking receive and also a blocking send can be equally matched by a non-blocking receive. That makes such constructs nonsensical:
// Receiver
MPI_Irecv(..., &request);
... do something ...
MPI_Wait(&request, &status);
// Sender
MPI_Isend(..., &request);
MPI_Wait(&request, MPI_STATUS_IGNORE);
MPI_Isend immediately followed by MPI_Wait is equivalent to MPI_Send and the following code is perfectly valid (and easier to understand):
// Receiver
MPI_Irecv(..., &request);
... do something ...
MPI_Wait(&request, &status);
// Sender
MPI_Send(...);
I have a modless Win32 API dialogbox as status box with a LISTBOX in it where I print some information of the communication between an IDE and the MSSCCI provider.
Everything works fine (the status messages are printed line by line and scrolled) unless I, as a IDE user, touch the status- dialogbox and try to move it around.
Then the status updating freezes (when clicking on the status dialogbox several times the "not responding" appear in the title bar) and with it the parent application (an IDE).
The program seems still to be running in the background (I also log to a file where the progress is "visible").
The dialogobox is not destroyed but hidden by the application when the task (getting several file from the repo) has finished. Later when a new task is started the dialogbox is shown again, the status message of the newly started task get printed and scrolled again as if nothing had happend.
I tried to catch the WM_MOVE and WM_MOVING in the dialogboxes callback function, set the statusbox the active window (see code). Nothing helped so far.
What do I have to do that the dialogbox does not freeze when the user moves it?
Any hints?
(By the way, when debugging, I can not move the dialogbox and the listbox in the dialogbox gets updated all the time and the parent get redrawn too)
Here some code (file processing loop):
pool = svnApiSvnIface.fp_svn_pool_create_ex(masterPool, NULL);
for(i=0; i<nFiles; i++)
{
WaspLoggerLogPrintf(0, "%s - Processing: '%s' \n",
__FUNCTION__,
StripFilename(lpFileNames[i]));
UpdateWindow(hwndParent);
SetActiveWindow (hwndStatusBox);
PrintMesgStatusBox("CheckFileStatus: for %s", StripFilename(lpFileNames[i]));
revison.kind = svn_opt_revision_unspecified;
:
Here the some code from the PrintMesgStatusBox() function:
if(UseStatusBox())
{
int lbIndex = 0;
int length = vsprintf(statusMessage, format, args);
int printedLength = 0;
while((printedLength + STATUSBOX_LINE_LENGTH) < length)
{
char tempChar = statusMessage[printedLength + STATUSBOX_LINE_LENGTH];
statusMessage[printedLength + STATUSBOX_LINE_LENGTH] = '\0';
SendDlgItemMessage(hwndStatusBox, IDC_LIST1, LB_ADDSTRING, 0, (LPARAM)&statusMessage[printedLength]);
statusMessage[printedLength + STATUSBOX_LINE_LENGTH] = tempChar;
printedLength += STATUSBOX_LINE_LENGTH;
}
SendDlgItemMessage(hwndStatusBox, IDC_LIST1, LB_ADDSTRING, 0, (LPARAM)&statusMessage[printedLength]);
//AUTOSCROLL
lbIndex = SendDlgItemMessage(hwndStatusBox, IDC_LIST1, LB_GETCOUNT, 0, 0) - 1;
//Scroll to the newest item (put lbIndex to the top of the lb)
SendDlgItemMessage(hwndStatusBox, IDC_LIST1, LB_SETTOPINDEX, lbIndex, 0);
//redraw
UpdateWindow(hwndStatusBox);
:
The issue was that the message queue seemed no longer to be processed due to my code looping and communicating to the SVN server for a long time.
Since I have not control over the IDE implementation I had to do it in my dll.
I the loop I implemented a function which consumes and dispatches the messages for the dialogbox (resp. all messages).
The results were different if all or only the dialogbox message were consumed:
Consuming dialogbox messages only: The dialogbox would updated after every SVN communication which results in a rather choppy UI response to the user action. But the IDE menus stay in accessible which is wanted.
Consuming all messages: The UI response to the user is relatively smooth. But the IDE menus are accessible and the IDE can be close or other actions start. This is unwanted.
Hence I stay with only consuming the dialogbox messages.
Some code (function processing messages):
void ProcessMessages(HWND hWnd, BOOLEAN peekHwndMsgsOnly)
{
MSG msg;
HWND peekHwnd = NULL;
if(peekHwndMsgsOnly)
{
peekHwnd = hWnd;
}
while(PeekMessage(&msg, peekHwnd, 0, 0, PM_REMOVE))
{
if(!IsDialogMessage(hWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
The loop originally blocking messages processing:
for(i=0; i<nFiles; i++)
{
/*
WaspLoggerLogPrintf(0, "%s - Processing: '%s' \n",
__FUNCTION__,
StripFilename(lpFileNames[i]));
*/
PrintMesgStatusBox("CheckFileStatus: for %s", StripFilename(lpFileNames[i]));
revison.kind = svn_opt_revision_unspecified;
youngest = SVN_INVALID_REVNUM;
internalfileName = svnApiSvnIface.fp_svn_dirent_internal_style(lpFileNames[i], pool);
if (updateFromRepo) { PrintMesgStatusBox(" Retrieving repo status..."); }
UpdateWindow(hwndParent);
ProcessMessages(hwndStatusBox, TRUE);
rtn = svnApiSvnIface.fp_svn_client_status4( &youngest, // svn_revnum_t *result_rev,
internalfileName, // const char *path,
&revison, // const svn_opt_revision_t *revision,
This might not be a very elegant solution but is serving the purpose.
I'm implementing a TCP/IP application on Windows 7 that loops around a socket recv() call. For small amount of data (< 5 MB) it works fine, but for large data (>20 MB), the recv fails in between.
Details: My app needs to communicate with HTTP server running , both running on same machine, in this scenerio, tcp app is sending heavy data to HTTP server
It gives error = 2, recv returns 0.
Error 2 means ENOENT, but what does it means?. Does anyone know what this is (in regards to a socket) and how I can get around this?
msgLen = recv(s,msg,BUFFER_SIZE,0);
if(msgLen > 0)
{
// do processing
}
else
{
printf("\n no data received .... msgLen=%d",msgLen);
printf("\n no data received .... errno=%d",errno);
}
Update Code as per comment
msgLen = recv(s,msg,BUFFER_SIZE,0);
if(msgLen > 0)
{
// do processing
}
else if(msgLen == 0)
{
printf("\n sender disconnected");
}
else
{
printf("\n no data received .... msgLen=%d",msgLen);
printf("\n no data received .... errno=%d",WSAGetLastError());
}
The error I get now is:
Firstly, recv = 0 many times, i.e. sender disconnected;
Finally, recv returns -1, and error = 10053.
My TCP/IP application is sending data to HTTP Server. The same works fine with small data, but the issue comes with large amount of data. Is HTTP server getting time out?
When recv() returns 0, it means the other party disconnected gracefully (assuming that your requested buffer size is not 0). recv() only provides an error code when it returns SOCKET_ERROR (-1). On Windows, you have to use WSAGetLastError() to get the error code, not errno, eg:
msgLen = recv(s,msg,BUFFER_SIZE,0);
if(msgLen > 0)
{
// do processing
}
else if (msgLen == 0)
{
printf("\n sender disconnected");
}
else
{
printf("\n no data received .... error=%d",WSAGetLastError());
}
Also keep in mind that if you are using a non-blocking socket, the error code may be WSAEWOULDBLOCK, which is not a fatal error. You can use select() to detect when the socket has data and then attempt the recv() again.