GMainLoop 和 TCP Listen 线程阻塞
GMainLoop and TCP Listen thread blocking
我需要你的帮助。
我有主循环 GMainLoop,附加了超时回调:
MainLoop = g_main_loop_new(NULL, FALSE);
g_timeout_add_seconds(Interval, TimeoutCallback, (gpointer) Rec);
g_main_loop_run(MainLoop);
并收听套接字:
int ControlServer::GStart()
{
int listenfd;
GIOChannel *in;
socklen_t addr_len;
listenfd = TcpListen(host, port, &addr_len);
in = g_io_channel_unix_new(listenfd);
g_io_add_watch(in, G_IO_IN, (GIOFunc) Handler, (gpointer) Rec);
g_io_channel_unref(in);
return 0;
}
一切都很好,超时功能正常工作,直到任何客户端未连接到侦听的套接字。连接后,超时在客户端连接时不起作用。我认为它与线程相连,因为默认情况下 GMainContext 中的所有操作都在一个线程中执行。我用这个修改了代码:
int ControlServer::GThStart()
{
int listenfd;
socklen_t addr_len;
GIOChannel *Channel;
GSource *Source;
GMainContext *Context;
listenfd = TcpListen(host, port, &addr_len);
Channel = g_io_channel_unix_new(listenfd);
Source = g_io_create_watch(Channel, G_IO_IN);
g_source_set_callback(Source, (GSourceFunc) Handler, (gpointer) Rec, NULL);
Context = g_main_context_new();
g_source_attach(Source, Context);
g_source_unref(Source);
return 0;
}
但是现在套接字被侦听,但没有任何客户端可以连接到它,并且从未调用过处理程序函数。
处理程序代码如下:
bool ControlServer::Handler(GIOChannel *in, GIOCondition condition, gpointer data)
{
Recorder *Rec = (Recorder *) data;
struct sockaddr_storage income;
int insock, newsock;
socklen_t income_len;
struct sockaddr peer;
socklen_t size;
Access *access;
insock = g_io_channel_unix_get_fd(in);
income_len = sizeof(income);
newsock = accept(insock, (struct sockaddr *) &income, &income_len);
size = sizeof(peer);
getpeername(newsock, &peer, &size);
struct sockaddr_in *ipv4 = (struct sockaddr_in *) &peer;
access = new Access(newsock, ipv4, MAXN);
access->Cycle(Rec);
delete access;
return true;
}
类"访问"检查客户端的权限,并在客户端或服务器未关闭连接时通过实现无限循环执行协议交换。
do
{
result = DoCycle(Rec);
sprintf(str, "DEBUG: DoCycle(Rec) returns '%d'n", result);
AppendLog(str, class_name, DEBUG);
} while (result != -1);
DoCycle() 仅在连接关闭或通过 TCP 交换数据时出错时才返回"-1"。
怎么了?谢谢!
问题出在函数int ControlServer::GThStart()
,您应该将GSource
添加到GMainLoop
的GMainContext
,而不是新的上下文,请尝试使用:
g_source_attach(Source,g_main_loop_get_context(MainLoop));
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 异常属于C++中的线程还是进程
- C++中的线程安全删除
- C++使用params创建线程函数会导致转换错误
- 类与私有变量的其他类之间的线程安全性
- CoInitialize()在单独的线程上崩溃而不返回
- c++中的线程池
- 线程之间的布尔停止信号
- 为什么std::async使用同一个线程运行函数
- 用于矢量处理的多个线程
- GMainLoop 和 TCP Listen 线程阻塞
- 使用websockettpp库在多线程程序中为endpoint.listen()创建一个单独的提升线程