C++ 11"移动"是一个很好的功能,但我发现当与"复制"同时使用时,很难避免代码重复(我们都讨厌这个).下面的代码是我实现的一个简单的循环队列(不完整),两个push()方法几乎相同,除了一行.
我遇到过很多像这样的情况.任何想法如何避免这种代码重复而不使用宏?
===编辑===
在这个特定的例子中,重复的代码可以被重构并放入一个单独的函数中,但有时这种重构是不可用的或者不能轻易实现.
#include <cstdlib>
#include <utility>
template<typename T>
class CircularQueue {
public:
CircularQueue(long size = 32) : size{size} {
buffer = std::malloc(sizeof(T) * size);
}
~CircularQueue();
bool full() const {
return counter.in - counter.out >= size;
}
bool empty() const {
return counter.in == counter.out;
}
void push(T&& data) {
if (full()) {
throw Invalid{};
}
long offset = counter.in % size;
new (buffer + offset) T{std::forward<T>(data)};
++counter.in;
}
void push(const T& data) {
if (full()) { …Run Code Online (Sandbox Code Playgroud) 我正在做一些C++绿色线程的研究,大多数boost::coroutine2和类似的POSIX函数一样makecontext()/swapcontext(),并计划在其上实现一个C++绿色线程库boost::coroutine2.两者都需要用户代码为每个新函数/协同程序分配一个堆栈.
我的目标平台是x64/Linux.我希望我的绿色线程库适合一般用途,因此堆栈应该根据需要进行扩展(合理的上限很好,例如10MB),如果堆栈在未使用太多内存时可能会收缩,那就太好了(不需要) ).我还没有想出一个合适的算法来分配堆栈.
经过一些谷歌搜索,我自己想出了几个选项:
mmap()希望内核足够聪明,可以保留未分配的物理内存,只在访问堆栈时分配.在这种情况下,我们受内核的支配.mmap(PROT_NONE)并设置一个SIGSEGV信号处理程序.在信号处理程序中,当SIGSEGV由堆栈访问引起时(被访问的内存在保留的大内存空间内),分配所需的内存mmap(PROT_READ | PROT_WRITE).这是这种方法的问题:mmap()不是异步安全,不能在信号处理程序内部调用.它仍然可以实现,但非常棘手:在程序启动期间为内存分配创建另一个线程,并用于pipe() + read()/write()从信号处理程序向线程发送内存分配信息.关于选项3的更多问题:
mmap()调用而极度分散时,内核/ CPU的性能/坏程度如何?read()被召唤?绿色线程的堆栈分配还有其他(更好的)选项吗?如何在其他实现中分配绿色线程堆栈,例如Go/Java?
我遇到了一个奇怪的C++代码行为,不确定它是编译器错误还是我的代码的未定义/未指定的行为.这是代码:
#include <unistd.h>
#include <iostream>
#include <thread>
struct Parent {
std::thread t;
static void entry(Parent* p) {
p->init();
p->fini();
}
virtual ~Parent() { t.join(); }
void start() { t = std::thread{entry, this}; }
virtual void init() { std::cout << "Parent::init()" << std::endl; }
virtual void fini() { std::cout << "Parent::fini()" << std::endl; }
};
struct Child : public Parent {
virtual void init() override { std::cout << "Child::init()" << std::endl; }
virtual void fini() override { std::cout << "Child::fini()" << …Run Code Online (Sandbox Code Playgroud) 我知道以下公式可用于将RGB图像转换为YUV图像.在下面的公式中,R,G,B,Y,U,V都是8位无符号整数,中间值是16位无符号整数.
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16
U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128
V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128
Run Code Online (Sandbox Code Playgroud)
但是当在OpenCL中使用该公式时,这是一个不同的故事.
1. 8位存储器写访问是可选扩展,这意味着一些OpenCL实现可能不支持它.
2.即使支持上述扩展,与32位写访问相比,它的速度也非常慢.
为了获得更好的性能,每4个像素将同时处理,因此输入为12个8位整数,输出为3个32位无符号整数(第一个代表4个Y样本,第二个代表4个Y样本,第二个代表4 U样品,最后一个代表4 V样品).
我的问题是如何直接从12个8位整数中获得这3个32位整数?是否有一个公式来获得这3个32位整数,或者我只需要使用旧公式得到12个8位整数结果(4 Y,4 U,4 V)并用位构造3个32位整数 - 运作?
我需要让我的 linux 可执行文件“编译一次,到处运行”。理论上是可以的,因为我的程序只使用非常基本的系统调用(网络 IO 和文件 IO 的系统调用)。在实践中,这是一个不同的故事:
我的开发平台是 Ubuntu 12.04,它有相当新的内核、glibc 和工具链。我首先尝试静态链接我的可执行文件,但该可执行文件拒绝在 centos 5(内核版本 2.6.18)上运行。如果可执行文件是动态链接的,动态加载程序 (ld.so) 将拒绝加载我的可执行文件。我什至尝试发布一个修改过的动态加载器(我将它修改为忽略内核版本),libc,libgcc_s,仍然不起作用,因为修改后的加载器总是尝试从系统加载 libc 并忽略随我的可执行。
我需要一个动态加载器,它会盲目加载我希望它加载的所有内容。有人知道 linux 上有这样的动态加载器吗?我不确定我是否朝着正确的方向前进,因此欢迎提出任何建议。
有没有办法将NULL指针访问转换为Linux下的C++异常?类似于Java中的NullPointerException.我希望以下程序能够成功返回,而不是崩溃(假设编译器在编译期间无法找出此NULL指针访问):
class NullPointerException {};
void accessNullPointer(char* ptr) {
*ptr = 0;
}
int main() {
try {
accessNullPointer(0);
} catch (NullPointerException&) {
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不期望任何标准的方法,因为C++下的NULL指针访问是未定义的 - 行为,只是想知道如何在x86_64 Linux/GCC下完成它.
我做了一些非常原始的研究,有可能:
sigaction()用于注册信号处理程序).如果程序被反汇编,也可以使用导致SIGSEGV的指令.以下是GCC手册页的引用(-fnon-call-exceptions):
生成允许捕获指令以抛出异常的代码.请注意,这需要在任何地方都不存在的特定于平台的运行时支持.此外,它只允许捕获指令抛出异常,即内存引用或浮点指令.它不允许从诸如"SIGALRM"之类的任意信号处理程序抛出异常.
看来这个"特定于平台的运行时"正是我想要的.任何人都知道这样的Linux/x86_64运行时?或者如果没有这样的运行时已经存在,请给我一些关于如何实现这样的运行时的信息?
我希望该解决方案也适用于多线程程序.
以下是用于创建部署的文件:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kloud-php7
namespace: kloud-hosting
spec:
replicas: 1
template:
metadata:
labels:
app: kloud-php7
spec:
containers:
- name: kloud-php7
image: 192.168.1.1:5000/kloud-php7
- name: kloud-nginx
image: 192.168.1.1:5000/kloud-nginx
ports:
- containerPort: 80
Run Code Online (Sandbox Code Playgroud)
Deployment 和 Pod 工作正常,但是在删除 Deployment 和生成的 ReplicaSet 后,我无法永久删除 spawn Pod。如果删除旧的 Pod,则会创建新的 Pod。
kubernetes集群使用kargo创建,包含4个节点,运行CentOS 7.3,kubernetes 1.5.6版
知道如何解决这个问题吗?
我需要通过 TCP 连接创建一个虚拟 IP 网络。托管系统是Linux,带有TUN/TAP内核驱动,很容易接收和重新注入虚拟网络的IP包。
困难的部分是将接收到的 IP 数据包传输到另一台主机。由于一些非技术原因,我只能通过 TCP 协议而不是 UDP 传输数据包。通过 UDP 传输 IP 数据包很容易,但使用 TCP 就变得很棘手,原因如下:
UDP协议不支持重传/重排序,就像IP一样。因此,如果为每个接收到的虚拟 IP 数据包发送一个 UDP 数据包,内核 TCP/IP 协议栈仍会看到虚拟 IP 数据包丢失/重复/重新排序(这些是 TCP/IP 正常工作所必需的,如果这些“特性”丢失,虚拟网络上的 TCP 连接速度会受到影响)。如果 IP 数据包通过 TCP 传输,则所有必需的“功能”都将丢失,除非它们以某种方式进行模拟。
看来我必须在 TCP 连接上伪造某种数据包重复/丢失/重新排序,或者修补内核 TCP/IP 协议堆栈。这两种选择都不容易。
我的问题还有其他更简单的解决方案吗?还是我只是进入了一个完全错误的方向?我都是耳朵。
==== 更新 ====
我正在考虑使用原始 IP 套接字(它可以在仍然使用 TCP 数据包的同时轻松摆脱物理网络上的所有 TCP 重传/重新排序内容)来传输接收到的虚拟网络 IP 数据包。但是在接收主机上,如何只接收我感兴趣的数据包并将所有其他 IP 数据包返回到内核 TCP/IP 堆栈?