在C 11中的背景中运行线程
Running thread in background in c++11
我有一个带有连接方法的类继续,但它挂在我的connect_to
方法中,直到线程执行停止。我记得我曾经在C#中使用线程,并且一旦我启动它们,它们就在后台跑了。
#ifndef _TCP_CLIENT_H_
#define _TCP_CLIENT_H_
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
void connection_thread(void *user);
class TCPClient
{
public:
SOCKET m_ConnectSocket = INVALID_SOCKET;
char m_recvbuf[BUFFER_LENGTH];
int m_recvbuflen = BUFFER_LENGTH;
struct addrinfo* m_result = NULL, *m_ptr = NULL, m_hints;
vector<PacketInfo*> m_packet_list;
PacketInfo* m_packet_data = new PacketInfo();
thread* m_conn_thread;
int state = 0;
char* ip_address;
unsigned int port = 0;
TCPClient() {}
~TCPClient() {
delete m_packet_data;
}
int Init_Sockets() {
WSADATA wsaData;
int iResult;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %dn", iResult);
return 0;
}
return 1;
}
int Connect_to(char* ip, unsigned int port_number) {
port = port_number;
ip_address = ip;
//thread conn_thread(connection_thread, this);
thread conn_thread([=]() {connection_thread(this); return 1; });
conn_thread.join();
state = 0;
return 1;
}
}; // end TCPClient class
void connection_thread(void *user) {
TCPClient * self = static_cast<TCPClient*>(user);
// connecting code here... //
self->state = CONNECTED;
do {
iResult = recv(self->m_ConnectSocket, self->m_recvbuf, self->m_recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %dn", iResult);
}
else if (iResult == 0) {
printf("Connection closedn");
self->state = DISCONNECTED;
}
else {
//printf("recv failed with error: %dn", WSAGetLastError());
}
}
while (iResult > 0);
}
#endif
螺纹按预期工作,并保持恒定循环,直到连接关闭。知道我缺少什么吗?
我有一个带有连接方法的课程,我正在启动其中的线程,调用它,加入它,我希望该线程在该线程中运行背景和程序执行将继续,但是它挂在我的连接_to方法中,直到线程执行停止
这实际上是加入线程应该做的!
如果您不想加入线程,那么简单地不。:)
,可能,您可能至少应该在类驱动器或其他某些时间中进行此操作,以便您的主线程在工作线程仍在执行时无法尝试结束。因为那将以眼泪结束...
在我看来,这是一个完美的例子,说明了为什么我们不应该编写代码行而不了解为什么我们这样做。:)您已经对conn_thread.join()
的含义做出了假设,这是错误的假设:在这种情况下要做的第一件事是阅读文档以确保您的假设成立。理想情况下,您会在编写代码之前阅读,但没关系。
它正在悬挂,因为对join()
的调用导致当前线程被暂停,直到连接线程完成为止,直到join()
的调用将返回。
conn_thread.join(); // Current thread will wait
// until conn_thread finishes.
您还在评论中提到,如果您不进行加入,那么您会得到一个堕胎。这是因为线程的破坏者调用terminate()
如果其代表的线程仍然是joinble
。
由于您的线程对象是本地的,因此在呼叫Connect_to()
的末尾被销毁。
int Connect_to(char* ip, unsigned int port_number) {
// Here you have defined a variable local to the function
// Thus its constructor is called here (which starts the thread)
thread conn_thread([=]() {connection_thread(this); return 1; });
// conn_thread.join();
}
// The destructor is called here.
// If the thread is still running at this point you will
// get a call to `terminate()`
那么您如何停止。
- 您可以调用
detach()
方法。 - 您可以使
thread
属于较大的上下文,因此不会被破坏。
调用detach()
不是一个好主意。当您失去所有对运行线程的引用和与之通信的引用变得很难。
我还注意到您的class TCPClient
thread* m_conn_thread;
这似乎没有使用。
如果将线程存储在此对象中,它将持续到对象(因此比函数更长)。由于对象的线程访问成员,因此对象显然应该持续使用。
所以我将进行以下更改:
// 1 Make the member a real variable not a pointer.
std::thread m_conn_thread;
// 2 Initialize this in the constructor.
TCPClient()
: m_conn_thread() // no thread created with this constructor.
{}
// 3 Create and assing a thread to this variable.
int Connect_to(char* ip, unsigned int port_number) {
// STUFF
m_conn_thread = std::move(std::thread([=]() {connection_thread(this); return 1; }));
// MORE STUFF
}
// Add a destructor that waits for the thread to join.
~TCPClient()
{
// As the thread is using members from this object
// We can not let this obect be destroyed until
// the thread finishes executing.
m_conn_thread.join();
// At this point the thread has finished.
// Destructor can now complete.
// Note: Without the join.
// This could potentially call terminate()
// as destroying the member m_conn_thread while the
// the thread is still running is bad.
}
- 使用基类中的派生方法运行线程,而无需使用模板
- 使用 ubuntu 终端在 c++ 上运行线程类的问题
- 将项目添加到队列时运行线程
- 运行线程和线程对象之间的关系
- 在 gtest 中运行线程
- 是否有一种可接受的运行线程或按顺序执行的方法
- 从类中运行线程
- 如何在第三方函数调用之前同时运行线程
- 在优先级最低的核心中运行线程
- 在C++中并行运行线程
- 在C 11中的背景中运行线程
- 在运行线程中处理事件
- 使用对象生存期运行线程
- WINAPI CreateThread并不总是运行线程
- 树莓派与 c++ 运行线程,在网络上发布数据
- 使用变量类型 std::function 运行线程
- Eclipse CDT 多线程调试不是最佳的 - 如何以独占方式运行线程
- 在 C 语言的后台运行线程
- 正在运行线程
- 在远程计算机上运行线程