关于listbox 排序问题

一个线程 收

DWORD WINAPI ThreadInProc(LPVOID lpv) {
    while (iThread)
    {
        if (0 < recv(sClient, Sin, sizeof(Sin), 0)) {
            sprintf_s(SinEx, sizeof(SinEx), "Server : %s", Sin);
            SendMessage(GetDlgItem(hClientDialog, IDC_LISTIN), LB_ADDSTRING, 0, (LPARAM)SinEx);
        }
    }
    return 0;

主线程 发

            GetDlgItemText(hClientDialog, IDC_EDITOUT, Sout, sizeof(Sout));
            if (send(sClient, Sout, sizeof(Sout),0)!= SOCKET_ERROR)
            {
                sprintf_s(SoutEx,sizeof(SoutEx), "Client Me : %s", Sout);
                SendMessage(GetDlgItem(hClientDialog,IDC_LISTIN), LB_ADDSTRING, 0,(LPARAM)SoutEx);
                SetDlgItemText(hClientDialog, IDC_EDITOUT, NULL);
            }


为啥 客户端的消息 没有插到服务器发来第一句的下一行

img

img

ChatGPT尝试为您解答,仅供参考
这可能是因为两个线程之间没有同步,导致收到的数据没有及时显示在列表框中。


在 Windows 系统中,你可以使用互斥体 (mutex) 或信号量 (semaphore) 来同步线程。互斥体用于互斥地访问共享资源,信号量则用于控制对共享资源的访问。你也可以使用事件 (event) 来实现线程同步。


你可以在收到数据后使用一个事件通知发送线程,并在发送线程收到事件后再发送数据。这样就可以保证收到的数据在发送的数据之前显示在列表框中。
如果你想使用互斥体来同步线程,可以使用以下代码:

HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);

// 线程 1 代码:
while (iThread)
{
    if (0 < recv(sClient, Sin, sizeof(Sin), 0))
    {
        WaitForSingleObject(hMutex, INFINITE); // 等待互斥体
        sprintf_s(SinEx, sizeof(SinEx), "Server : %s", Sin);
        SendMessage(GetDlgItem(hClientDialog, IDC_LISTIN), LB_ADDSTRING, 0, (LPARAM)SinEx);
        ReleaseMutex(hMutex); // 释放互斥体
    }
}

// 线程 2 代码:
GetDlgItemText(hClientDialog, IDC_EDITOUT, Sout, sizeof(Sout));
WaitForSingleObject(hMutex, INFINITE); // 等待互斥体
if (send(sClient, Sout, sizeof(Sout), 0) != SOCKET_ERROR)
{
    sprintf_s(SoutEx, sizeof(SoutEx), "Client Me : %s", Sout);
    SendMessage(GetDlgItem(hClientDialog, IDC_LISTIN), LB_ADDSTRING, 0, (LPARAM)SoutEx);
    SetDlgItemText(hClientDialog, IDC_EDITOUT, NULL);
}
ReleaseMutex(hMutex); // 释放互斥体

你也可以使用信号量来同步线程。

HANDLE hSemaphore = CreateSemaphore(NULL, 0, 1, NULL);

// 线程 1 代码:
while (iThread)
{
    if (0 < recv(sClient, Sin, sizeof(Sin), 0))
    {
        sprintf_s(SinEx, sizeof(SinEx), "Server : %s", Sin);
        SendMessage(GetDlgItem(hClientDialog, IDC_LISTIN), LB_ADDSTRING, 0, (LPARAM)SinEx);
        ReleaseSemaphore(hSemaphore, 1, NULL); // 释放信号量
    }
}

// 线程 2 代码:
GetDlgItemText(hClientDialog, IDC_EDITOUT, Sout, sizeof(Sout));
WaitForSingleObject(hSemaphore, INFINITE); // 等待信号量
if (send(sClient, Sout, sizeof(Sout), 0) != SOCKET_ERROR)
{
    sprintf_s(SoutEx, sizeof(SoutEx), "Client Me : %s", Sout);
    SendMessage(GetDlgItem(hClientDialog, IDC_LISTIN), LB_ADDSTRING, 0, (LPARAM)SoutEx);
    SetDlgItemText(hClientDialog, IDC_EDITOUT, NULL);
}

在使用互斥体、信号量或事件同步线程时,一定要注意资源的释放,尤其是在线程退出时,应该及时释放资源,避免资源泄漏。


下面是使用事件同步线程的完整代码:

// 线程 1 代码:
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
while (iThread)
{
    if (0 < recv(sClient, Sin, sizeof(Sin), 0))
    {
        sprintf_s(SinEx, sizeof(SinEx), "Server : %s", Sin);
        SendMessage(GetDlgItem(hClientDialog, IDC_LISTIN), LB_ADDSTRING, 0, (LPARAM)SinEx);
        SetEvent(hEvent); // 通知线程 2
    }
}
CloseHandle(hEvent);

// 线程 2 代码:
HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, NULL);
GetDlgItemText(hClientDialog, IDC_EDITOUT, Sout, sizeof(Sout));
WaitForSingleObject(hEvent, INFINITE); // 等待线程 1 通知
if (send(sClient, Sout, sizeof(Sout), 0) != SOCKET_ERROR)
{
    sprintf_s(SoutEx, sizeof(SoutEx), "Client Me : %s", Sout);
    SendMessage(GetDlgItem(hClientDialog, IDC_LISTIN), LB_ADDSTRING, 0, (LPARAM)SoutEx);
    SetDlgItemText(hClientDialog, IDC_EDITOUT, NULL);
}
CloseHandle(hEvent);