小编Art*_*yom的帖子

添加Windows对POSIX项目的支持......有多痛苦?值得努力吗?

我正在尝试/考虑使CppCMS - C++ Web Framework项目更加跨平台.

今天我可以轻松支持Linux,OpenSolaris,FreeBSD甚至Cygwin.但是当涉及Native Windows时,它变得非常痛苦:

情况概述:

  1. 我是POSIX/Linux开发人员,我对Visual Studio和Win32 API等Native Windows开发工具几乎不熟悉.但是我为这个平台做了一些工作,所以我理解Windows的局限性和事实是完全不同的世界.
  2. 这是一个使用在Unix世界中流行的API的Web项目,例如:在大多数UNIX Web服务器中实现的CGI,FastCGI和SCGI; 但我知道我无法在IIS中使用它,因为它不支持TCP/IP上的FastCGI(仅限Windows管道).

    因此,即使它可以工作,它也可能仅在Apache的Windows端口上运行.

  3. 我在POSIX API上大量接力:

    • Pref-forking允许在崩溃的情况下保持高生存能力(Windows不支持),因此这个功能将会丢失.
    • 我使用了一些文件锁定功能(但我可以放弃它而不用分叉)
    • 我大量使用本机pthreads,即使我可以用Boost.Thread替换它们
  4. 我可能永远无法支持Visual Studio(可能是2010年支持C++ 0x),因为我继续使用C++ 0x decltype/auto功能或typeof/__ typeof__扩展,这是我工作的大多数编译器所支持的:gcc,英特尔,太阳工作室.(说实话:我可以在没有它们的情况下工作,但它使框架用户的生活更容易.
  5. 我在autotools上大量接力,我无法用CMake,bjam或朋友替换它们,因为当涉及到支持国际化,交叉复制,包管理时,他们只是没有给我一个解决方案.
  6. 有许多令人烦恼的问题,例如在Windows下缺少gmtime_r或localtime_r,以及许多其他需要我重写它们或用第3部分库替换它们的内容.
  7. 仍有许多"类似UNIX"的库移植到Win32,如:iconv,gcrypt和其他一些像libdbi一样几乎没有移植的库,它们对Windows有许多限制.

底线:

有很多非常重要的工作要做,即使它完成了,它可能只适用于MingW工具而不是Windows程序员熟悉的" 本机 "工具.

所以,我的问题是:

  • 这样的MingW港口值得努力吗?这有助于建立更大的社区吗?
  • 有没有人有过将大型项目从POSIX环境移植到Win32 API的痛苦经历?
  • 它对Windows开发人员有用吗?

编辑:

对我来说,了解有多少Windows开发人员更喜欢使用开源开发工具MingW而不是像VS这样的Microsoft开发解决方案,这一点也很重要.

编辑#2:关于"原生"Windows解决方案和IIS的清除.

事实上,用IIS运行框架确实很难.我解释:

  • 该项目与标准 Web服务器API相关,如FastCGISCGI,允许通过sinlge套接字接受许多请求.因此,在应用程序方面,我接受新请求继续它并返回答案.有时几个线程处理多个请求.

    因此,实现一个或两个标准协议我打开与任何现有服务器的通信:Apache,lighttpd,nginx,cherokee ......或任何其他服务器; 除了IIS之外

  • IIS具有FastCGI的实现,但是......它仅支持每个本地进程的1个连接,仅由Web服务器控制...

所以...绝对没有标准的方法将我的应用程序连接到IIS.

请注意,我实现了标准的 Web服务器API,我没有实现既不是IIS专有的ISAPI也不是Apache专有的API,即使是第二个更重要的是针对UNIX世界.

所以,只是Windows IIS Web世界还没有为这样的项目做好合作准备,所以如果有人在Windows下使用它,它会将它用于更开放的Web服务器.

winapi porting posix mingw

5
推荐指数
1
解决办法
1573
查看次数

最常见的内存/资源泄漏错误

所有优秀的C++程序员都知道如何避免泄漏内存(或套接字等资源):

  1. 总是使用智能指针,i.e.:std::auto_ptr, boost::shared_ptr.
  2. 始终注意对象的所有权:谁拥有,谁引用,谁负责等.

但是,内存泄漏仍然会发生.当您在程序中发现内存泄漏时,即使您使用上述技术,也要指出最常见的问题.

我开始:

有时您忘记将基类的析构函数定义为虚拟.所以派生类引用的所有派生类都没有被正确销毁并因此泄露.

c++ memory-leaks

5
推荐指数
2
解决办法
6015
查看次数

如何使用 Boost Asio 减少编译时间

Boost.Asio 是一个很棒的库,但它有一个巨大的缺点——编译时间极慢。一个简单的HTTP协议实现(真的很简单)(大约1k行代码)在GCC 4.4下编译需要大约13.5s!

我尝试使用 PCH,但它并没有太多地改善编译时间(大约仅 1 秒)。

那么有没有关于如何使 Boost.Asio 编译时间更快的教程?

例如,我应该为哪个类准确包含哪些标头。

例如,我使用:io_servicetcp::ip::socketstcp::ip::acceptordeadline_timer、 缓冲区和一些函数,如async_readasync_write

有什么建议么?

PS:只要有可能,我都会使用 pimpl。

c++ boost-asio compilation-time

5
推荐指数
1
解决办法
5941
查看次数

异步事件循环设计和问题

我正在使用epoll/devpoll/kqueue/poll/select(包括windows-select)设计异步套接字IO的事件循环.

我有两个执行IO操作的选项:

非阻止模式,在EAGAIN上进行调查

  1. 将套接字设置为非阻塞模式.
  2. 读/写套接字.
  3. 如果操作成功,则将完成通知发布到事件循环.
  4. 如果我得到EAGAIN,请将套接字添加到"选择列表"并轮询套接字.

轮询模式:轮询然后执行

  1. 添加套接字以选择列表并轮询它.
  2. 等待通知它是可读写的
  3. 读/写
  4. 将完成通知发送到sucseeds的事件循环

对我来说,在普通模式下使用时,首先需要较少的系统调用,特别是对于写入套接字(缓冲区非常大).此外,它似乎可以减少"选择"执行次数的开销,尤其是当你没有像epoll/devpoll/kqueue那样可以扩展的东西时,它会很好.

问题:

  • 第二种方法有什么优点吗?
  • 在许多操作系统上对套接字/文件描述符进行非阻塞操作是否存在任何可移植性问题:Linux,FreeBSD,Solaris,MacOSX,Windows.

注意:请不要建议使用现有的event-loop/socket-api实现

c c++ asynchronous nonblocking event-loop

5
推荐指数
1
解决办法
3494
查看次数

为什么非法cookie由浏览器发送并由Web服务器接收(rfc 2109,2965)?

根据RFC 2109,2965 cookie的值可以是HTTP令牌或带引号的字符串,而令牌不能包含非ASCII字符.

  1. Cookie的RFC 2109RFC2965
  2. HTTP的RFC 2068和2616令牌定义:http://tools.ietf.org/html/rfc2616#page-16

但是我发现Firefox浏览器(3.0.6)按原样发送带有utf-8字符串的cookie,我测试的三个Web服务器(apache2,lighttpd,nginx)按原样将该字符串传递给应用程序.

例如,来自浏览器的原始请求:

$ nc -l -p 8080
GET /hello HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.9) Gecko/2009050519 Firefox/2.0.0.13 (Debian-3.0.6-1)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1255,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: wikipp=1234; wikipp_username=??????
Cache-Control: max-age=0
Run Code Online (Sandbox Code Playgroud)

和apache,nginx和lighttpd HTTP_COOKIECGI变量的原始响应:

wikipp=1234; wikipp_username=??????
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

cookies webserver rfc

5
推荐指数
1
解决办法
2040
查看次数

为派生类提供模板特化的最简单方法

我有以下场景:

class my_base { ... }

class my_derived : public my_base { ... };


template<typename X>
struct my_traits;
Run Code Online (Sandbox Code Playgroud)

我想专门my_traits用于从my_base包括派生的所有类,例如:

template<typename Y> // Y is derived form my_base.
struct my_traits { ... };
Run Code Online (Sandbox Code Playgroud)

我在添加标签、成员my_base以使其更简单方面没有问题。我已经看到了一些技巧,但我仍然感到迷茫。

如何以简单而简短的方式做到这一点?

c++ inheritance template-specialization

5
推荐指数
1
解决办法
1410
查看次数

_fullpath vs GetFullPathName

有什么区别:_fullpath和GetFullPathName

当然,我的意思是分别比较他们的ANSI/Unicode变体

  • 安西:_fullpathvsGetFullPathNameA
  • Uni:_wfullpathvsGetFullPathNameW

看来_fullpath有更漂亮和更简单的API,因为它允许分配缓冲你,但我只是想,如果我更换GetFullPathNameW_wfullpath我会错过?

c winapi

5
推荐指数
1
解决办法
2163
查看次数

AsyncContext 和 I/O 错误处理(当对等断开连接时)

我正在使用 Servlet 3.0 的javax.servlet.AsyncContext接口实现服务器发送的事件。

但是,我无法理解我应该如何处理对等断开连接等 I/O 错误。

对于给定的AsyncContext ac = request.startAsync(),我可以调用ac.getResponse().getWriter().print(something)然后ac.getResponse.getWriter().flush()它工作正常。但是,当客户端断开连接时,我不会收到错误消息——即使我附加了一个侦听器,onError也不会调用它的方法。

我用 Jetty 8 和 Tomcat 7 对它进行了测试,似乎与客户端的断开连接没有报告给应用程序。

如何检测通信错误?

tomcat comet jetty servlet-3.0 jakarta-ee

5
推荐指数
1
解决办法
1652
查看次数

从Python API而不是saved_model_cli中提取(或设置)输入/输出TF张量名称信息

我用 Keras/TF2.5 训练了一个简单的模型并将其保存为保存模型。

tf.saved_model.save(my_model,'/path/to/model')
Run Code Online (Sandbox Code Playgroud)

如果我通过检查它

saved_model_cli show --dir /path/to/model --tag_set serve --signature_def serving_default
Run Code Online (Sandbox Code Playgroud)

我得到这些输出/名称:

inputs['conv2d_input'] tensor_info:
  dtype: DT_FLOAT
  shape: (-1, 32, 32, 1)
  name: serving_default_conv2d_input:0
outputs['dense'] tensor_info:
  dtype: DT_FLOAT
  shape: (-1, 2)
  name: StatefulPartitionedCall:0
Run Code Online (Sandbox Code Playgroud)

名称serving_default_conv2d_inputStatefulPartitionedCall实际上可以用于推断。

我想使用 python API 提取它们。如果我通过加载模型来查询它:

>>> m=tf.saved_model.load('/path/to/model')
>>> m.signatures['serving_default'].inputs[0].name
'conv2d_input:0'
>>> m.signatures['serving_default'].outputs[0].name
'Identity:0'
Run Code Online (Sandbox Code Playgroud)

我得到完全不同的名字。

问题:

  1. 如何从 python API 中serving_default_conv2d_input提取这些名称?StatefulPartitionedCall
  2. 或者,当我打电话时如何定义/修复名称tf.saved_model.save
  3. 这是什么:0意思?

还有附带问题:

如何通过 SavedModel 将 TF 模型部署到生产环境?

python inference tensorflow tf.keras

5
推荐指数
1
解决办法
1456
查看次数

在写入被阻止的套接字上使用TCP Keep-Alive获取断开连接通知

我使用TCP Keep-Alive选项来检测死连接.它适用于使用读取套接字的连接:

setsockopt(mysock,...) // set various keep alive options

epoll_ctl(ep,mysock,{EPOLLIN|EPOLERR|EPOLLHUP},)
epoll_wait -> (exits after several seconds when remove host disconnects cable)
Run Code Online (Sandbox Code Playgroud)

Epoll等待在套接字上使用EPOLLIN | EPOLLHUP退出而没有问题.

但是,如果我尝试向socket写入很多东西,直到我得到EAGAIN然后轮询读取和写入,我在断开电缆时没有出错:

setsockopt(mysock,...) // set various keep alive options

while(send() != EAGAIN)
   ;
epoll_ctl(ep,mysock,{EPOLLIN|EPOLLOUT|EPOLERR|EPOLLHUP},)
epoll_wait -> --- Never exits!!!! even when the cable of the remove host is disconnected!!!
Run Code Online (Sandbox Code Playgroud)
  • 怎么解决这个问题?
  • 有没有人见过类似的问题?
  • 任何可能的方向?

编辑:附加信息

当我监控与wireshark的通信时,在第一种情况下(读取)我会在几秒钟内得到一次ack请求.但在第二种情况下,我根本检测不到.

linux epoll tcp keep-alive

4
推荐指数
1
解决办法
1万
查看次数