c++控制台程序线程问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++控制台程序线程问题相关的知识,希望对你有一定的参考价值。

写一个socket 的服务器端代码 我的目标是 对于每一个TCP连接服务器都建立2个线程进行连接 一个线程进行对数据的接受现实 另外一个线程以广播的形式发送给每个连接的客服端。
DWORD WINAPI ClientThreadAccept(LPVOID lpParameter)

struct clientadd *ClientSock=(struct clientadd *)lpParameter;
struct clientadd *find;
find=ClientSock->next;
SOCKET ClientSocket=ClientSock->next->ClientSocket;
int Ret=0;
char RecvBuffer[MAX_PATH];
while (true)

memset(RecvBuffer,0,sizeof(RecvBuffer));
Ret=recv(ClientSocket,RecvBuffer,MAX_PATH,0); //阻塞函数
if (0==Ret||SOCKET_ERROR==Ret)

cout<<"客服端退出"<<endl;
break;

for (int i = 0; i <ClientSock->CommentNum; i++)

if (find->ClientSocket==ClientSocket)

break;


cout<<"接收到IP:"<<inet_ntoa(find->ClientAddr.sin_addr)<<"端口号:"<<find->ClientAddr.sin_port<<"信息:"<<RecvBuffer<<endl;

return 0;

DWORD WINAPI ClientThreadSend(LPVOID lpParameter)

struct clientadd *ClientSock=(struct clientadd *)lpParameter;
struct clientadd *find;
cout<<"test send thread"<<endl;
return 0;

当我进入第一个线程recv不是阻塞函数 进程不是挂起么?
该进程挂起主进程还在进行 应该创建第二个进程 而我第二个进程却没有显示符。一直阻塞在recv
求大神解释下
hThreadSned=CreateThread(NULL,0,ClientThreadSend,(const LPVOID)ClientPoint,0,NULL);
if (NULL==hThreadSned)

cout<<"建立发送数据线程失败"<<endl;
break;

hThreadAccept=CreateThread(NULL,0,ClientThreadAccept,(const LPVOID)ClientPoint,0,NULL);
if (NULL==hThreadAccept)

cout<<"建立接受数据线程失败"<<endl;
break;

CloseHandle(hThreadAccept);
CloseHandle(hThreadSned);
这个是主函数里面的 创建线程的

设计问题
(1)tcp是基于连接的、双向的,你一个tcp连接对应两个线程,一个收、一个发,很少有这么设计的(虽然逻辑上是可以的);一般一个线程处理一个连接,同时做收发处理
(2)你的代码不全,我没太看明白;但一般服务器主线程循环调用accept,接收新的连接请求(并生成新的socket),然后把这个socket传递给新线程处理。

代码问题
(1)你的ClientThreadSend和ClientThreadAccept创建完,后面就直接CloseHandle;很可能线程还没有执行就被CloseHandle掉了;如果你的线程只处理简单事情、没有无限循环,那么就不需要主线程CloseHandle,让线程自己执行完退出就可以了。追问

我的思路:代码一开始写的是阻塞模式下 然后想用是用多线程来实现异步 一开始设计确实是没有设计好。

如果你的线程只处理简单事情、没有无限循环,那么就不需要主线程CloseHandle,让线程自己执行完退出就可以了 这句话不明白

追答

主线程保留子线程句柄,一般用于同步和关闭;

如果子线程不是设计为一个服务(内部不是无限循环),执行完相应逻辑就自动退出(代码层面就是会执行return语句),就不需要主线程主动关闭子线程了。

参考技术A 第一个线程应该是ClientThreadSend吧,先起的ClientThreadSend,然后是ClientThreadAccept
输出也应该是这个顺序。追问

如何使多线程的异步

追答

socket和fifo都可以实现异步通信,这部分可以找本书来看看。
网络上例子也有很多。

参考技术B Ret=recv(ClientSocket,RecvBuffer,MAX_PATH,0);  //阻塞函数   

if (0==Ret||SOCKET_ERROR==Ret)



      cout<<"客服端退出"<<endl;

break;

你这个是判断远端客户端是否关闭连接了吧?如果远端没关闭那就会一直阻塞啊。

追问

是啊 我这些代码都写错了 要写成非阻塞模式的SOCKET

追答

不太清楚你想干什么,不过大致猜一下应该是对一个客户端链表里面的所有SOCKET发送相同数据吧。

追问

是的 广播 一开始想用多线程异步写 现在就直接用非阻塞写了

追答

像这些你可以用一些三方库,比如 Boost.asio 、ACE 之类的,大大节省时间,而且错误回调处理方便。

参考技术C 你把主进程代码发一下,是不是创建线程那里没写对

以上是关于c++控制台程序线程问题的主要内容,如果未能解决你的问题,请参考以下文章

C++控制台程序怎样使主函数无限循环

C++ 多线程 操作List 的问题

将 Python 控制台集成到 GUI C++ 应用程序中

Python、线程、GIL 和 C++

从 C# 代码调试 C++ exe

为啥 Windows 10 在我的程序中启动额外线程?