小编Art*_*yom的帖子

如何在Linux上执行x86,arm,GCC和icc上的原子操作?

每个现代操作系统都提供一些原子操作:

  • Windows有Interlocked*API
  • FreeBSD有 <machine/atomic.h>
  • Solaris有 <atomic.h>
  • Mac OS X有 <libkern/OSAtomic.h>

对Linux有什么相似之处?

  • 我需要它在大多数Linux支持的平台上工作,包括:x86,x86_64和 arm.
  • 我需要它至少在GCC和英特尔编译器上工作.
  • 我不需要使用像glib或qt这样的第三方库.
  • 我需要它在C++中工作(C不是必需的)

问题:

  • __sync_*并非所有平台(ARM)都支持GCC原子内置,并且英特尔编译器不支持.
  • AFAIK <asm/atomic.h>不应该在用户空间中使用,我根本没有成功使用它.此外,我不确定它是否适用于英特尔编译器.

有什么建议?

我知道有很多相关的问题,但有些问题指出__sync*哪些对我来说是不可行的(ARM),有些人指出asm/atomic.h.

也许有一个内联汇编库可以为GCC执行此操作(ICC支持gcc汇编)?

编辑:

仅对添加操作有一个非常局部的解决方案(允许实现原子计数器但不能锁定需要CAS的自由结构):

如果您使用libstc++(英特尔编译器使用libstdc++),那么您可以使用或__gnu_cxx::__exchange_and_add中定义的.取决于编译器版本.<ext/atomicity.h><bits/atomicity.h>

但是,我仍然希望看到支持CAS的东西.

c c++ linux atomic

56
推荐指数
2
解决办法
3万
查看次数

Servlet-3异步上下文,如何进行异步写操作?

问题描述

Servlet-3.0 API允许分离请求/响应上下文并在以后回复它.

但是,如果我尝试编写大量数据,例如:

AsyncContext ac = getWaitingContext() ;
ServletOutputStream out = ac.getResponse().getOutputStream();
out.print(some_big_data);
out.flush()
Run Code Online (Sandbox Code Playgroud)

对于Tomcat 7和Jetty 8,它实际上可能会阻塞 - 并且它确实阻塞了琐碎的测试用例.教程建议创建一个可以处理这种设置的线程池 - 这通常是对传统10K架构的反作用.

但是,如果我有10,000个打开的连接和一个让我们说10个线程的线程池,那么即使1%的具有低速连接或仅阻塞连接的客户端阻塞线程池并完全阻止彗星响应或减慢其速度也足够了显著.

预期的做法是获得"写就绪"通知或I/O完成通知,而不是继续推送数据.

如何使用Servlet-3.0 API完成,即如何获得:

  • I/O操作的异步完成通知.
  • 通过写入就绪通知获取非阻塞I/O.

如果Servlet-3.0 API不支持,那么是否有任何特定于Web Server的API(如Jetty Continuation或Tomcat CometEvent)允许真正异步处理此类事件而无需使用线程池伪造异步I/O.

有人知道吗?

如果这不可能,您可以参考文档确认吗?

示例代码中的问题演示

我附上了模拟事件流的代码.

笔记:

  • 它使用ServletOutputStream该抛出IOException来检测断开连接的客户端
  • 它发送keep-alive消息以确保客户端仍在那里
  • 我创建了一个线程池来"模拟"异步操作.

在这样的例子中,我明确定义了大小为1的线程池来显示问题:

  • 启动一个应用程序
  • 从两个终端运行curl http://localhost:8080/path/to/app(两次)
  • 现在发送数据 curd -d m=message http://localhost:8080/path/to/app
  • 两个客户都收到了数据
  • 现在暂停其中一个客户端(Ctrl + Z)并再次发送消息 curd -d m=message http://localhost:8080/path/to/app
  • 观察到另一个非挂起的客户端没有收到任何信息,或者在传输消息后停止接收保持活动请求,因为其他线程被阻止.

我想在不使用线程池的情况下解决这样的问题,因为使用1000-5000个开放连接,我可以非常快地耗尽线程池.

下面的示例代码.


import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import …
Run Code Online (Sandbox Code Playgroud)

java comet servlet-3.0

50
推荐指数
2
解决办法
3万
查看次数

如何enable_shared_from_this父和派生

我有简单的基础和派生类,我想要两个shared_from_this().

这个简单的方案:

class foo : public enable_shared_from_this<foo> {
    void foo_do_it()
    {
        cout<<"foo::do_it\n";
    }
public:
    virtual function<void()> get_callback()
    {
        return boost::bind(&foo::foo_do_it,shared_from_this());
    }
    virtual ~foo() {};
};

class bar1 : public foo , public enable_shared_from_this<bar1> {
    using enable_shared_from_this<bar1>::shared_from_this;
    void bar1_do_it()
    {
        cout<<"foo::do_it\n";
    }
public:
    virtual function<void()> get_callback()
    {
        return boost::bind(&bar1::bar1_do_it,shared_from_this());
    }
};
Run Code Online (Sandbox Code Playgroud)

导致tr1::bad_weak_ptr以下代码中的异常:

shared_ptr<foo> ptr(shared_ptr<foo>(new bar1));
function<void()> f=ptr->get_callback();
f();
Run Code Online (Sandbox Code Playgroud)

所以在"谷歌搜索"之后我找到了以下解决方案:

class bar2 : public foo {
    void bar2_do_it()
    {
        cout<<"foo::do_it\n";
    }
    shared_ptr<bar2> shared_from_this()
    {
        return boost::static_pointer_cast<bar2>(foo::shared_from_this());
    }
public: …
Run Code Online (Sandbox Code Playgroud)

c++ boost smart-pointers

31
推荐指数
3
解决办法
2万
查看次数

如何在GUI框架中集成Boost.Asio主循环,如Qt4或GTK

有没有办法将Boost.Asio与Qt4(首选)或GTK主循环集成?GTK像API一样提供poll(2),因此技术上应该是可行的.Qt提供了自己的网络层,但我更喜欢使用为Boost.Asio编写的现有代码.我想在使用额外线程的情况下集成它们.

有没有参考如何为Qt4(首选)或GTKmm做这个?

谢谢.

编辑

我想澄清一些事情,以使答案更容易.Qt和GTKmm都提供"选择类似"功能:

所以,问题是,如何将现有的"选择器/轮询器"作为反应器集成到Boost.Asio中io_service.今天,Boost.Asio可以使用select,kqueue,epoll,/ dev/poll和iocp作为reactor/proactor服务.我想将它集成到GUI框架的主循环中.

欢迎任何建议和解决方案(更好).

gtk qt4 event-loop boost-asio

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

XSS攻击和样式属性

已知样式属性XSS攻击如:

<DIV STYLE="width: expression(alert('XSS'));">
Run Code Online (Sandbox Code Playgroud)

要么

<DIV STYLE="background-image: url(javascript:alert('XSS'))">
Run Code Online (Sandbox Code Playgroud)

我见过的所有例子使用了表达式或网址功能 - 基本上就像需要"(和")"这样的功能.

我正在考虑使用过滤样式标签的方法,我会使用以下(近似)语法检查它们:

identifier: [a-zA-Z_][a-zA-Z0-9\-]*
number: [0-9]+
string: '[a-zA-Z_0-9 ]*'
value : identifier | number | string | number + "(em|px)" | number +"%"
entry: identifier ":" value (\s value )*
style: (entry ;)*
Run Code Online (Sandbox Code Playgroud)

所以基本上我允许带有数值的ASCII属性或非常有限的字符串值(基本上是字体名称)不允许使用看起来像调用的任何东西.

问题是这还够好吗?有没有可能做类似的攻击:

<DIV STYLE="this-is-js-property: alert 'XSS';">
Run Code Online (Sandbox Code Playgroud)

并成功?

谁能想到这种测试的XSS漏洞?

说清楚

我需要样式属性,因为许多工具(如TinyMCE)使用它们并过滤无害的样式属性会严重损害功能.

所以我更喜欢通过常见的情况删除所有可能使用@ import,url,expression等的东西.还要确保基本的css语法没问题.

回答

不,由于点击顶级漏洞,它不安全.

html javascript xss coding-style

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

C++ 0x中的新unicode字符

我正在建立一个允许我以各种编码方式获取字符串的API,包括utf8,utf16,utf32和wchar_t(根据操作系统可能是utf32或utf16).

  1. 新的C++标准已推出了新的类型char16_t,并char32_t没有这个的sizeof歧义,应在今后的使用,所以我想支持他们为好,但问题是,它们会干扰正常的uint16_t,uint32_t,wchar_t类型不允许超载,因为他们可以指同一类型?

    class some_class {
    public:
        void set(std::string); // utf8 string
        void set(std::wstring); // wchar string utf16 or utf32 according
                                 // to sizeof(wchar_t)
        void set(std::basic_string<uint16_t>)
                             // wchar independent utf16 string
        void set(std::basic_string<uint32_t>);
                             // wchar independent utf32 string
    
    #ifdef HAVE_NEW_UNICODE_CHARRECTERS
        void set(std::basic_string<char16_t>)
                             // new standard utf16 string
        void set(std::basic_string<char32_t>);
                             // new standard utf32 string
    #endif
    };
    
    Run Code Online (Sandbox Code Playgroud)

    所以我可以写:

    foo.set(U"Some utf32 String");
    foo.set(u"Some utf16 string");
    
    Run Code Online (Sandbox Code Playgroud)
  2. 什么是typedef的std::basic_string<char16_t>std::basic_string<char32_t>今天有:

    typedef …
    Run Code Online (Sandbox Code Playgroud)

c++ unicode c++11 char16-t char32-t

25
推荐指数
1
解决办法
5743
查看次数

使用向后兼容的使用Boost的ABI创建库

我正在研究某个C++库(或更多框架).我想让它向后兼容以前的版本,不仅保留了API兼容性,还保留了ABI(就像Qt那样出色的工作).

我使用Boost的许多功能,对我来说,这使得向后兼容性变得不可能,除非我强迫用户拥有完全相同(有时是旧版本)的B​​oost.

有没有办法(没有重写1/2 Boost)在其命名空间周围做一些"前缀"/重命名它以防止它干扰用户版本的Boost?

例如,我的libXYZ使用Boost 1.33并且它有类boost::foo.在版本1.35 boost::foo升级并添加了新成员,因此,boost::foo从1.33和1.35不兼容ABI.因此,libXYZ的用户必须使用Boost 1.33或使用Boost 1.35重新编译libXYZ(可能已经以XYZ无法编译的方式破坏了某些API).

注意:我说的是带有ELF的UNIX/Linux操作系统,其中动态链接类似于静态链接,因此您无法链接两个不同版本的库,因为符号会产生干扰.

我可能想到的一个合适的解决方案是将Boost放在其他一些私有命名空间中.因此,libXYZ将使用::XYZ::boost::foo而不是::boost::foo.这可以防止与用户可能使用的其他版本的Boost冲突.

因此,libXYZ将继续使用Boost 1.33与其他命名空间静态或动态链接,假设它:

  • 不会暴露Boost API.
  • 将保持稳定的私有版本的公开API.

有没有办法用Boost做这些事情?

编辑:最后我决定创建一个脚本,将源中的所有boost符号重命名为某个自定义符号.

基本原理:构建过程的简化,独立于编译器可见性支持,它的可见性仅适用于动态库,对于静态,这不起作用,因此我需要为每种类型的库提供单独的构建和依赖.

该脚本可在那里找到:http://art-blog.no-ip.info/files/rename.py

编辑2:最新版本的Boost BCP支持命名空间重命名.

c++ unix compatibility boost abi

24
推荐指数
2
解决办法
6673
查看次数

为什么C++回调C函数需要"extern C"?

我在Boost代码中找到了这样的例子.

namespace boost {
   namespace {
     extern "C" void *thread_proxy(void *f)
     {
       ....
     }

   } // anonymous
   void thread::thread_start(...)
   {
       ...
       pthread_create(something,0,&thread_proxy,something_else);
       ...
   }
} // boost
Run Code Online (Sandbox Code Playgroud)

你为什么真的需要这个extern "C"

很明显,该thread_proxy函数是私有内部的,我不认为它会被破坏为"thread_proxy",因为我实际上根本不需要它.

实际上,在我编写的所有代码中,我在许多平台上运行,我从未使用过,extern "C"而且这个代码与普通函数一样正常.

为什么要extern "C"添加?


我的问题是extern "C"函数污染了全局命名空间,并且它们实际上并没有像作者所期望的那样被隐藏.

这不是重复的! 我不是在谈论破坏和外部联系.在此代码中很明显,外部链接是不需要的!

答: C和C++函数的调用约定不一定相同,因此您需要使用C调用约定创建一个.参见C++标准的7.5(p4).

c c++ callback extern-c

17
推荐指数
3
解决办法
4361
查看次数

这些奇怪的环境变量是什么?

GetEnvironmentString()用来获取程序的环境变量.

每个程序都有这样的结果:

=::=::\
Run Code Online (Sandbox Code Playgroud)

我不知道这是什么意思?

这是代码:

LPWCH lpEnvString=GetEnvironmentStringsW();
 LPWSTR lpszVariable=(LPWSTR)lpEnvString;
 while (*lpszVariable)
 {
     wprintf(L"%s\n",lpszVariable);
     lpszVariable+=wcslen(lpszVariable)+1;
 }
 FreeEnvironmentStringsW(lpEnvString);
Run Code Online (Sandbox Code Playgroud)

此外,如果我们开始列出这些变量,我们会看到如下内容:

=::=::\
=C:=C:\Users\username\value
=ExitCode=00000001
ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\artik\AppData\Roaming
CommonProgramFiles=C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
...
Run Code Online (Sandbox Code Playgroud)

另一方面,getenv("=ExitCode")getenv("=C:")返回NULL.

你能否提供这个"功能"的正确文档,例如getenv()忽略这样的字符串以及如何处理这些值?

windows winapi environment-variables

17
推荐指数
1
解决办法
1945
查看次数

在MSVC++中编码源字符集编码,如gcc"-finput-charset = CharSet"

我想创建一些处理编码的示例程序,特别是我想使用宽字符串,如:

wstring a=L"grüßen";
wstring b=L"???? ????!";
wstring c=L"??";
Run Code Online (Sandbox Code Playgroud)

因为这些是示例程序.

对于将源代码视为UTF-8编码文本的gcc,这绝对是微不足道的.但是,简单的编译在MSVC下不起作用.我知道我可以使用转义序列对它们进行编码,但我更愿意将它们保存为可读文本.

是否有任何选项可以指定为"cl"的命令行开关以使其工作?那里有任何命令行开关,如gcc'c-finput-charset

谢谢,

如果不是,你会如何建议让文字对用户自然?

注意:将BOM添加到UTF-8文件不是一种选择,因为它变得不可由其他编译器编译.

注意2:我需要它在MSVC版本> = 9 == VS 2008中工作

真正的答案:没有解决方案

c++ unicode visual-c++

15
推荐指数
2
解决办法
6419
查看次数