gpt4 book ai didi

VC++ 2022 Unaccountable Abort() blocking the UI while supposed aborted worker thread goes on working fine indefinitely (!?)(VC++2022不可解释的Abort()阻塞用户界面,而假定已中止的工作线程无限期地正常工作(!?))

转载 作者:bug小助手 更新时间:2023-10-25 13:55:55 27 4
gpt4 key购买 nike



I am not that qualified in C++ programming but I really can't get through this issue.
My project is as follows :
Connecting to a WIFI server with the TCP protocol . The server keeps sending lines of text : no problem . It systematically connects. A dedicated thread is cycling receiving the text and displaying it in an edit window. It is supposed to terminate when I click on a "disconnect" button. But I can't click on that button because I get a message (Cancel, Retry, Ignore) telling me Abort() has been called. Meanwhile the messages are still displayed and the parallel debug window shows me the thread comfortably going on working.

我对C++编程不是很在行,但我真的解决不了这个问题。我的项目如下:使用TCP协议连接到WiFi服务器。服务器继续发送文本行:没问题。它系统地连接在一起。专用线程正在循环接收文本并将其显示在编辑窗口中。当我点击“断开”按钮时,它应该会终止。但我不能点击该按钮,因为我收到一条消息(取消、重试、忽略),告诉我已经调用了Abort()。与此同时,消息仍然显示,并行调试窗口向我显示线程轻松地继续工作。


This is the code of my WndProc :

这是我的WndProc的代码:



LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_ACTIVATEAPP:
{ Create_incoming_NMEA_messages_box();
Create_info_message_box();
Create_push_button();
}

case WM_COMMAND:
{
int wmId = LOWORD(wParam);

switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;

case IDC_MAIN_BUTTON: // connect - disconnect
{
if (!Connected)
{
if (Connect_addr(szServer, szPort) == 0) // == 0 => connected
{
Connected = true;
SendMessage(hEditOut, WM_SETTEXT, NULL, (LPARAM)"Connected at Host = 10.0.0.1 / Port = 10111");
Button_SetText(hWndButton, "Disconnect");


thread TCPThread(Loop_while_connected); // thread constructed and launched

}
}
else {
Connected = false;
SendMessage(hEditOut, WM_SETTEXT, NULL, (LPARAM)"Disconnected");
//TCPThread.join();
Button_SetText(hWndButton, "Connect");
}

}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{

PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);

EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}


Just to be precise the Connect_addr(szServer, szPort) function is as follows :

准确地说,Connect_addr(szServer,szPort)函数如下所示:


int Connect_addr(char* host, char* port)
{

// Set up Winsock INITIALIZATION
WSADATA WsaDat;
int nResult = WSAStartup(MAKEWORD(2, 2), &WsaDat);
if (nResult != 0)
{
MessageBox(hWnd, "Winsock initialization failed", "Critical Error", MB_ICONERROR);
SendMessage(hWnd, WM_DESTROY, NULL, NULL);

}
struct addrinfo hints; // defines address type
struct addrinfo* result, * rp;

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; // Allow IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // TCP socket
hints.ai_flags = 0;
hints.ai_protocol = IPPROTO_TCP;


int s = getaddrinfo(host, port, &hints, &result);


// getaddrinfo() returns a list of address structures.
// Try each address until we successfully connect(x). x = socket ID
// If socket(x) (or connect(x)) fails, we (close the socket
// and) try the next address.

int resconn = -1; // result of the connection attempt

for (rp = result; rp != NULL; rp = rp->ai_next) // rp = pointer to the chained list of all IP addresses managed by the client machine
{
ConnectSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (ConnectSocket == -1)
continue;

resconn = connect(ConnectSocket, rp->ai_addr, rp->ai_addrlen);
if (resconn == -1)
{
resconn = WSAGetLastError();
MessageBox(0, "Non connect\u00E9", "Erreur connexion", MB_ABORTRETRYIGNORE);
}
else break; // Success

}
freeaddrinfo(result); // No longer needed
return resconn;
}


This function works fine. The problem seems to be with thread TCPThread(Loop_while_connected) in the WindProc code (case IDC_MAIN_BUTTON).

此功能运行良好。问题似乎与WindProc代码(Case IDC_Main_BUTTON)中的线程TCPThread(Loop_While_Connected)有关。


The thread function is Loop_while_connected here:

线程函数是Loop_While_Connected,如下所示:


const unsigned HISTORY_BUFF_SIZE = 1000000;
char szHistory[HISTORY_BUFF_SIZE] = { 0 }; // NMEA messages accumulating buffer
int nKr = 0; // sums the received Kr to reset szHistory to start before saturating the buffer
const unsigned int Buff_Size = 10240;

void Loop_while_connected()
{
int inDataLength = 0;

if (Connected)
do
{
char szIncoming[Buff_Size];
ZeroMemory(szIncoming, Buff_Size);
inDataLength = 0;

inDataLength = recv(ConnectSocket, szIncoming, Buff_Size, 0);


if (inDataLength > 0)

{
strncat_s(szHistory, _countof(szHistory), szIncoming, inDataLength);
nKr += inDataLength;

SendMessage(hEditIn, WM_SETTEXT, sizeof(szIncoming) - 1, reinterpret_cast<LPARAM>(szHistory));
PostMessage(hEditIn, EM_SETSEL, 0, -1); // Select all
PostMessage(hEditIn, EM_SETSEL, -1, -1); // Unselect and stay at the end pos
PostMessage(hEditIn, EM_SCROLLCARET, 0, 0); // Set scrollcaret to the current Pos

}

if (nKr >= HISTORY_BUFF_SIZE - Buff_Size) {
ZeroMemory(szHistory, sizeof(szHistory));
nKr = 0;
}

} while (Connected);
}

It starts like this :

它是这样开始的:


enter image description here

在此处输入图像描述


When I click on connect it connects but issues an error message like this while the text is always scrolling :

当我单击连接时,它会连接,但会在文本始终滚动时发出如下错误消息:


enter image description here

在此处输入图像描述


Now if I hit "Retry to debug" as indicated the thread actually stops and I get the debug window showing me an error at the end of the destruction procedure.

现在,如果我按指示点击“重试调试”,线程实际上停止了,我得到调试窗口,在销毁过程的末尾显示一个错误。


enter image description here

在此处输入图像描述


I surely have made something stupid somewhere . I have checked that my thread was joinable as soon it was launched but I still can't understand why my call to TCPThread.join() in the WndProc procedure on disconnecting is rejected by the compiler. Maybe both problems are related ?
Than you in advance for your help.

我肯定在什么地方做了件蠢事。我已经检查了我的线程一启动就是可接合的,但我仍然不能理解为什么在断开连接时在WndProc过程中对TCPThread.Join()的调用被编译器拒绝。也许这两个问题是相关的?比你提前感谢你的帮助。


更多回答
优秀答案推荐

In fact there is nothing properly stupid there. Microsoft VC++ Win32 does not seem to comply to the C++ 11 multithreading "simplicity"(constructor/destructor) .
A line like

事实上,那里没有什么真正愚蠢的东西。Microsoft VC++Win32似乎不符合C++11多线程“简单性”(构造函数/析构函数)。像这样的一行


    thread TCPThread(Loop_while_connected);

compiles without problem but eventually bugs at run time.

编译时没有问题,但最终会在运行时出现错误。


The solution is to use _beginthread instead like this

解决方案是使用_eginthline,如下所示


(HANDLE)_beginthread(Loop_while_connected, 0,NULL);

provided the function Loop_while_connected is rendered consistent with the call to _beginthread by passing a pointer to the thread ID as a parameter in its header like this :

假设函数Loop_While_Connected通过将指向线程ID的指针作为其标头中的参数传递,使其与对_eginside的调用保持一致,如下所示:


void Loop_while_connected(void* pThrID)

{
}

{}


更多回答

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com