小编Dim*_* C.的帖子

如何避免消息队列被淹没?

我正在开发一个应用程序,该应用程序分为瘦客户端和服务器部分,通过 TCP 进行通信。我们经常让服务器向客户端进行异步调用(通知)以报告状态变化。这可以避免服务器浪费太多时间来等待客户端的确认。更重要的是,它避免了死锁

这种死锁可能会发生如下。假设服务器将同步发送状态更改通知(请注意,这是一个有点构造的示例)。当客户端处理通知时,客户端需要同步向服务器询问信息。但是,服务器无法响应,因为他正在等待问题的答案。

现在,通过异步发送通知可以避免这种死锁,但这会带来另一个问题。当异步调用的速度超过处理速度时,调用队列就会不断增长。如果这种情况持续足够长的时间,呼叫队列将完全满(充满消息)。我的问题是:发生这种情况该怎么办?

我的问题可以总结如下。我真的必须在不阻塞发送通知(冒着淹没消息队列的风险)和发送通知时阻塞(冒着引入死锁的风险)之间做出选择吗?有什么技巧可以避免消息队列泛滥吗?

注意:重复一遍,发送通知时服务器不会停止。它们是异步发送的。

注意:在我的示例中,我使用了两个通信进程,但两个通信线程也存在同样的问题。

language-agnostic concurrency multithreading synchronization

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

如何处理未经检查的异常?

Java有编译器检查异常.当我转换到C++时,我了解到它没有检查异常.起初,我一直在使用异常处理,因为它是一个很棒的功能.但是,过了一段时间我放弃了它,因为我遇到了一种情况,每个函数都可能抛出异常.由于我编写的函数中只有一小部分可以抛出异常(比如说最多只有25%),我发现对不能抛出任何不可接受的函数进行异常处理的开销.

因此,我很惊讶有很多开发人员更喜欢未经检查的异常.因此,我很想知道他们是如何处理这个问题的.如果语言不支持检查异常,您如何避免执行不必要的异常处理的开销

备注:我的问题同样适用于C++和C#,也可能适用于所有其他不具备编译器检查异常处理功能的语言.

c# java exception-handling exception

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

以编程方式在Windows Vista上注册.dll(使用DllRegisterServer)

可以使用以下步骤注册.DLL,而不是调用regsvr32.exe:

HINSTANCE hLib = ::LoadLibraryEx(dllPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
HRESULT (STDAPICALLTYPE* lpDllEntryPoint)(void);
(FARPROC&)lpDllEntryPoint = ::GetProcAddress(hLib, "DllRegisterServer");
const HRESULT hRes = (*lpDllEntryPoint)();
Run Code Online (Sandbox Code Playgroud)

这在Windows XP上运行正常.遗憾的是,它在Vista上失败了,但只有一些特定的DLL.hRes变成E_ACCESSDENIED.我想这是一个安全问题.有谁知道如何从Windows Vista上的代码注册.DLL?

注意:我在运行此代码时以管理员身份登录.

windows dll windows-vista

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

如何选择应用程序应链接到的VC 2008 DLL的版本?

我正在使用Visual Studio 2008 SP1 for C++.编译时,Visual Studio需要选择应该链接应用程序的哪个版本的CRT和MFC DLL,版本9.0.21022.8(= RTM),9.0.30729.17(= SP1)或9.0.30729.4148(=带安全更新的SP1) .我想知道如何选择将两个版本中的哪一个链接起来.有人知道吗?

注意:这在使用专用程序集时很重要,因为您需要知道要与.exe一起复制哪些版本的VC 9.0 DLL.

请注意,_BIND_TO_CURRENT_VCLIBS_VERSION标志仅确保清单中包含正确的版本.运行时的DLL版本选择显然不是基于清单文件中包含的版本完成的.即使清单文件说应该使用v21022,.exe也会使用v30729 .DLL.我知道这一点,因为它使用std :: tr1 :: weakptr,这在v21022中不存在.

c++ windows dll dependencies visual-studio-2008

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

什么可能导致进行HttpWebRequest调用的巨大开销?

当我使用小块中的HttpWebRequest(在Silverlight上)发送/接收数据时,我通过"localhost"连接测量500字节/秒的非常小的吞吐量.当以大块发送数据时,我得到2 MB/s,这5000倍.

有谁知道什么可能导致这个令人难以置信的巨大开销?

附加信息:

  • 我正在使用HTTP POST方法
  • 我在Firefox 3.6和Internet Explorer 7上都进行了性能测量.两者都显示了类似的结果.
  • 我的CPU只加载了10%(四核,实际上是40%)
  • WebClient显示了类似的结果
  • WCF/SOAP显示了类似的结果

更新:我使用的Silverlight客户端代码本质上是我自己的WebClient类实现.我写它的原因是因为我注意到WebClient存在相同的性能问题,我认为HttpWebRequest可以调整性能问题.遗憾的是,这没有用.实施如下:

public class HttpCommChannel
{
    public delegate void ResponseArrivedCallback(object requestContext, BinaryDataBuffer response);

    public HttpCommChannel(ResponseArrivedCallback responseArrivedCallback)
    {
        this.responseArrivedCallback = responseArrivedCallback;
        this.requestSentEvent = new ManualResetEvent(false);
        this.responseArrivedEvent = new ManualResetEvent(true);
    }

    public void MakeRequest(object requestContext, string url, BinaryDataBuffer requestPacket)
    {
        responseArrivedEvent.WaitOne();
        responseArrivedEvent.Reset();

        this.requestMsg = requestPacket;
        this.requestContext = requestContext;

        this.webRequest = WebRequest.Create(url) as HttpWebRequest;
        this.webRequest.AllowReadStreamBuffering = true;
        this.webRequest.ContentType = …
Run Code Online (Sandbox Code Playgroud)

.net silverlight performance http httpwebrequest

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

如何将数据传递给将在不同线程中运行的C++ 0x lambda函数?

重要更新:显然我在提出这个问题时得出了错误的结论.感谢我发现的响应,lambda函数[=]()在多线程场景中运行良好.我为提出这个令人困惑的问题而道歉.请投票结束,因为这不是问题.


在我们公司,我们编写了一个库函数,在一个单独的线程中异步调用一个函数.它使用继承和模板魔法的组合工作.客户端代码如下所示:

DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, &DemoThread::SomeFunction, stringToPassByValue);
Run Code Online (Sandbox Code Playgroud)

自从引入lambda函数以来,我想将它与lambda函数结合使用.我想写下面的客户端代码:

DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=]()
{
    const std::string someCopy = stringToPassByValue;
});
Run Code Online (Sandbox Code Playgroud)

更新:与我在提出这个问题时首先相信的情况相反,此代码运行正常.

现在,使用Visual C++ 2010,此代码不起作用.会发生什么stringToPassByValue是不复制.相反,"按值捕获"功能通过引用传递数据.结果是,如果函数在stringToPassByValue超出范围后执行,则应用程序崩溃,因为它的析构函数已经被调用.

所以我想知道:是否可以将数据作为副本传递给lambda函数

注意:一种可能的解决方案是修改我们的框架以传递lambda参数声明列表中的数据,如下所示:

DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=](const std::string stringPassedByValue)
{
    const std::string someCopy = stringPassedByValue;
}
, stringToPassByValue); …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11

5
推荐指数
0
解决办法
1544
查看次数

深层复制操作是否递归复制它不拥有的子变量?

给定一个具有它不拥有的变量的对象; 也就是说,变量由聚合而不是合成组成.深层复制操作是复制变量还是仅复制链接?

language-agnostic terminology deep-copy

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

代码重用有哪些缺点?

几年前,我们需要一个C++ IPC库来通过TCP进行函数调用.我们选择了一个并在我们的应用中使用它.过了一会儿,很明显它没有提供我们需要的所有功能.在我们软件的下一个版本中,我们将第三方IPC库丢弃,并将其替换为我们自己编写的库.从那时起,我有时会怀疑这是否是一个好的决定,因为它已被证明是相当多的工作,显然感觉就像重新发明轮子.所以我的问题是:代码重用是否有缺点证明这种重新发明的合理性?

language-agnostic code-reuse

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

为什么微软不想阻碍单声道和月光?

微软有意阻止跨平台软件的发生.Windows和Linux之间的不兼容性是人们不会大量迁移到Linux的主要原因.Mono和Moonlight项目都试图消除这个障碍.

因此,我想知道开始在Mono或Moonlight平台上开发是否风险不大,因为微软可能会阻挠这些跨平台的努力.

.net mono moonlight

4
推荐指数
2
解决办法
527
查看次数

如何在C++中记录异常情况?

在编写函数时,我的实现经常看起来像这样:

  • 调用子功能
  • 如果此子功能无法执行(由于异常情况):记录此故障并中止当前功能
  • 否则继续调用其他子功能,这反过来可能会失败

关键部分是伐木.每个失败的函数都应该在日志中添加简短描述.这样,在处理异常的级别,可以向用户显示详细的错误消息.

例如,考虑一个可以创建新用户帐户的应用程序,并且数据库连接存在问题.以下反向堆栈跟踪结果:

  • SQLDriverConnect() - >"SQLDriverConnect错误:未找到数据源且未指定默认驱动程序"
  • OpenDatabaseConnection() - >"无法打开数据库连接"
  • CreateUser() - >"无法创建新用户"
  • ValidateAndSaveNewUserAccount() - >"无法保存用户配置文件"
  • 捕获异常并将记录的消息显示给用户

使用例外功能,我将按如下方式实现:

void CreateUser()
{
    try {
        OpenDatabaseConnection();
    }
    catch(std::exception& e) {
        e.AddLog("Failed to create the new user");
        throw;
    }
    //...
}
Run Code Online (Sandbox Code Playgroud)

使用简单的返回值,我写下以下内容:

bool CreateUser(Log& log)
{
    if (!OpenDatabaseConnection(log))
    {
        log.Add("Failed to create the new user");
        return false;
    }
    //...
    return true;
}
Run Code Online (Sandbox Code Playgroud)

我发现两种实现都同样好.因此,我没有看到使用异常的优势.我很清楚异常处理通常被认为是一个有用的功能,但我真的不明白为什么.很久以前,我广泛使用异常处理,但我没有看到它的大优势,所以现在我再也不用它了.因此我的问题:

  • 使用异常,如何更简洁地在C++中实现?
  • 如果不是,那么抛出异常而不是返回"成功"布尔值的优点是什么呢?

注意:我使用术语日志记录 "收集对错误的解释,以便稍后可以将其呈现给用户".我宁愿不将该解释存储在日志消息的全局集合中(在内存中,在文件中或在数据库中),因为它直接描述了特定的异常.

更新:感谢您的回复.我知道只有当用户不需要有关错误的详细反馈时,例外才有用.(如果我误解了这个,请纠正我.)

c++ logging exception-handling exception

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