- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在编写一个并行神经网络模拟器,我最近在我的代码中遇到了一个让我很困惑的问题(假设我只是一个中级 C++ 程序员,所以也许我遗漏了一些明显的东西?)。 .. 我的代码涉及一个“服务器”和许多客户端(工作人员),它们从服务器获取工作并将结果返回给服务器。这是服务器部分:
#include <iostream>
#include <fstream>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <errno.h>
#include <sys/ioctl.h>
void advanceToNextInputValue(std::ifstream &trainingData, char &nextCharacter)
{
nextCharacter = trainingData.peek();
while(nextCharacter != EOF && !isdigit(nextCharacter))
{
sleep(1);
trainingData.get();
sleep(1);
nextCharacter = trainingData.peek();
}
}
int main()
{
// Create a socket,...
int listenerSocketNum = socket(AF_INET, SOCK_STREAM, 0);
// Name the socket,...
sockaddr_in socketAddress;
socklen_t socketAddressLength = sizeof(socketAddress);
inet_pton(AF_INET, "127.0.0.1", &(socketAddress.sin_addr));
socketAddress.sin_port = htons(9988);
bind(listenerSocketNum, reinterpret_cast<sockaddr*>(&socketAddress), socketAddressLength);
// Create a connection queue for worker processes waiting to connect to this server,...
listen(listenerSocketNum, SOMAXCONN);
int epollInstance = epoll_create(3); // Expected # of file descriptors to monitor
// Allocate a buffer to store epoll events returned from the network layer
epoll_event* networkEvents = new epoll_event[3];
// Add the server listener socket to the list of file descriptors monitored by epoll,...
networkEvents[0].data.fd = -1; // A marker returned with the event for easy identification of which worker process event belongs to
networkEvents[0].events = EPOLLIN | EPOLLET; // epoll-IN- since we only expect incoming data on this socket (ie: connection requests from workers),...
// epoll-ET- indicates an Edge Triggered watch
epoll_ctl(epollInstance, EPOLL_CTL_ADD, listenerSocketNum, &networkEvents[0]);
char nextCharacter = 'A';
std::ifstream trainingData;
// General multi-purpose/multi-use variables,...
long double v;
signed char w;
int x = 0;
int y;
while(1)
{
y = epoll_wait(epollInstance, networkEvents, 3, -1); // the -1 tells epoll_wait to block indefinitely
while(y > 0)
{
if(networkEvents[y-1].data.fd == -1) // We have a notification on the listener socket indicating a request for a new connection (and we expect only one for this testcase),...
{
x = accept(listenerSocketNum,reinterpret_cast<sockaddr*>(&socketAddress), &socketAddressLength);
networkEvents[y-1].data.fd = x; // Here we are just being lazy and re-using networkEvents[y-1] temporarily,...
networkEvents[y-1].events = EPOLLIN | EPOLLET;
// Add the socket for the new worker to the list of file descriptors monitored,...
epoll_ctl(epollInstance, EPOLL_CTL_ADD, x, &networkEvents[y-1]);
trainingData.open("/tmp/trainingData.txt");
}
else if(networkEvents[y-1].data.fd == x) // Worker is waiting to receive datapoints for calibration,...
{
std::cout << "nextCharacter before call to ioctl: " << nextCharacter << std::endl;
ioctl(networkEvents[y-1].data.fd, FIONREAD, &w);
std::cout << "nextCharacter after call to ioctl: " << nextCharacter << std::endl;
recv(networkEvents[y-1].data.fd, &v, sizeof(v), MSG_DONTWAIT); // Retrieve and discard the 'tickle' from worker
if(nextCharacter != EOF)
{
trainingData >> v;
send(networkEvents[y-1].data.fd, &v, sizeof(v), MSG_DONTWAIT);
advanceToNextInputValue(trainingData, nextCharacter);
}
}
y--;
}
}
close(epollInstance);
return 0;
}
这是客户端部分:
#include <arpa/inet.h>
int main()
{
int workerSocket = socket(AF_INET, SOCK_STREAM, 0);
// Name the socket as agreed with the server:
sockaddr_in serverSocketAddress;
serverSocketAddress.sin_family = AF_INET;
serverSocketAddress.sin_port = htons(9988);
inet_pton(AF_INET, "127.0.0.1", &(serverSocketAddress.sin_addr));
// Connect your socket to the server's socket:
connect(workerSocket, reinterpret_cast<sockaddr*>(&serverSocketAddress), sizeof(serverSocketAddress));
long double z;
while(1)
{
send(workerSocket, &z, sizeof(z), MSG_DONTWAIT); // Send a dummy result/tickle to server,...
recv(workerSocket, &z, sizeof(z), MSG_WAITALL);
}
}
我遇到问题的代码部分如下(来自服务器):
std::cout << "nextCharacter before call to ioctl: " << nextCharacter << std::endl;
ioctl(networkEvents[y-1].data.fd, FIONREAD, &w);
std::cout << "nextCharacter after call to ioctl: " << nextCharacter << std::endl;
在这里(至少在我的系统上),在某些情况下,对 ioctl 的调用基本上消除了“nextCharacter”的值,我不知道如何或为什么!
这些是我期望得到的结果:
$ ./server.exe
nextCharacter before call to ioctl: A
nextCharacter after call to ioctl: A
nextCharacter before call to ioctl: 1
nextCharacter after call to ioctl: 1
nextCharacter before call to ioctl: 9
nextCharacter after call to ioctl: 9
nextCharacter before call to ioctl: 2
nextCharacter after call to ioctl: 2
nextCharacter before call to ioctl: 1
nextCharacter after call to ioctl: 1
nextCharacter before call to ioctl: 1
nextCharacter after call to ioctl: 1
nextCharacter before call to ioctl: 1
nextCharacter after call to ioctl: 1
nextCharacter before call to ioctl: 2
nextCharacter after call to ioctl: 2
nextCharacter before call to ioctl: ÿ
nextCharacter after call to ioctl: ÿ
(带有变音符号的小写'y'是文件结束字符EOF)
这些是我得到的结果(请注意,我们最终陷入了无限循环,因为停止条件依赖于 nextCharacter 的值,而 nextCharacter 已被清除,因此它永远不会停止):
$ ./server.exe
nextCharacter before call to ioctl: A
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: 1
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: 9
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: 2
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: 1
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: 1
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: 1
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: 2
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: ÿ
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: ÿ
nextCharacter after call to ioctl:
nextCharacter before call to ioctl: ÿ
nextCharacter after call to ioctl:
.
.
.
如果我在这部分(在服务器中)注释掉任何 sleep 语句:
void advanceToNextInputValue(std::ifstream &trainingData, char &nextCharacter)
{
nextCharacter = trainingData.peek();
while(nextCharacter != EOF && !isdigit(nextCharacter))
{
sleep(1);
trainingData.get();
sleep(1);
nextCharacter = trainingData.peek();
}
}
然后我得到了我期望得到的结果,...
这是我正在使用的生成文件:
$ cat Makefile
all: server client
server: server.cpp
g++ server.cpp -o server.exe -ansi -fno-elide-constructors -O3 -pedantic-errors -Wall -Wextra -Winit-self -Wold-style-cast -Woverloaded-virtual -Wuninitialized -Winit-self
client: client.cpp
g++ client.cpp -o client.exe -ansi -fno-elide-constructors -O3 -pedantic-errors -Wall -Wextra -Winit-self -Wold-style-cast -Woverloaded-virtual -Wuninitialized -Winit-self
使用如下所示的 trainingData.txt 文件:
$ cat trainingData.txt
15616.16993666375,15616.16993666375,9.28693983312753E20,24.99528974548316,16.91935342923897,16.91935342923897,1.386594632397968E6,2.567209162871251
所以我是发现了一个新错误还是我只是愚蠢? :) 老实说,我不明白为什么用 FIONREAD 调用 ioctl 应该告诉我套接字上有多少字节等待读取,应该以任何方式影响变量 'nextCharacter' 的值,.. .
请注意,这是原始程序的缩减版本,它仍然设法重现问题(至少在我的系统上),所以请记住,上面的代码片段中有些东西可能没有意义:)
特里
最佳答案
来自 man ioctl_list
:
FIONREAD int *
也就是说,FIONREAD
需要一个指向整数的指针,但您传递的是一个指向 signed char
的指针。
解决方案:改变你的:
signed char w;
到
int w;
否则您将遭受未定义行为。
您所看到的解释可能是编译器将 w
和 nextCharacter
变量一起放在内存中,前者的溢出覆盖了值后者。
关于c++ - 使用 FIONREAD 调用 ioctl() 会在明显的竞争条件下产生奇怪的副作用,,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27487525/
在一个简单的 MFC 应用程序中,我需要有一个不断轮询 ioctl 事件的工作线程。起初,我试图在 while 循环中使用非重叠 ioctl 来实现这一点。我的想法是,如果 ioctl 没有立即完成
据我所知,ioctl 数字由驱动程序明确定义并在内核中注册。 我正在使用 python 中的一些代码来查询操纵杆状态。我已阅读this doc about joystick api , this do
您好,我收到此错误:ioctl:设备的 ioctl 不合适如下所示的 ioctl() 调用。 fd = open(mount, O_RDONLY); destid = ioctl(fd, TRACEF
我正在编写用作伪驱动程序的 Linux 内核模块 (LKM) - 我无法弄清楚如何在 LKM 之间进行 IOCTL 调用 (wait.c)和用户级程序 (user.c)。 设备驱动程序的魔数(Magi
以 resetting a serial port 为例在 Linux 中,我想翻译以下片段 fd = open(filename, O_WRONLY); ioctl(fd, USBDEVFS_RES
嘿,我在尝试从 python 调用 ioctl linux 系统调用时遇到问题。 在 C 应用程序中运行以下行,我设法获取给定 linux 命名空间文件描述符的父文件描述符。 #define NS_G
struct file_operations中的unlocked_ioctl的签名是 long (*unlocked_ioctl) (struct file *, unsigned int, unsi
if((err = ioctl(fd, IOC_CARD_LOCK, &lock)) < 0) { printf("ioctl failed and returned errno %d \n
抱歉,如果这是一个菜鸟问题,但我正在为游戏开发一个软件“附加”。我通过驱动程序执行此操作只是因为反作弊不支持环 0 检测。我还没有看到太多关于如何使用 IOCTL 的信息,我想知道您是否可以发送自定义
我正在尝试为允许“现金抽屉”附件的销售点系统编写代码。打开现金抽屉的手册中提供了代码(使用 IOCTL 在 C++ 中)。由于我在 C# .NET 中编码,是否可以在 C# 中执行类似的操作,或者我是
我编写了一个 IOCTL 驱动程序和一个相应的 ioctl 应用程序,其中包含一个包含命令的头文件。 #include #include #include #include #include
我正在使用 ioctl() 函数调用来获取管道端可用数据的大小,并根据该大小分配内存。 为此,我将此代码段编写为 if((read(mg_in, &byte, 1)) == 1)
最近我在c中遇到了ioctl函数,在探索时我不明白为什么我们要为这个特定代码传递标准输入文件描述符以及它的作用是什么?。 #include #include #include #include
我正在做一个nvme-cli的测试工具(用c写的,可以在linux上运行)。 出于 SSD 验证目的,我实际上是在寻找自定义命令(例如,I/O 命令,写入然后读取相同的内容,最后比较两个数据是否相同)
拿一个串口。串行端口可以调用带有TIOCMIWAIT 的ioctl 来等待信号变化。但是,如果串行端口以非阻塞方式打开,如何使用 select、poll 或 epoll 之类的东西来中断事件-当像CT
我有 #define IOCTL_ALLOC_MSG _IO(MAJOR_NUM, 0) #define IOCTL_DEALLOC_MSG _IO(MAJOR_NUM, 1) 在头文件中。 在我写的
我对 ioctl 有疑问(我认为)。 该软件是一个 debian 包,它在机器的引导过程中安装,然后立即启动。该软件通过使用/etc/network/interfaces 设置网络。 IP 和网络掩码
我正在 Android 应用程序中处理一些路由功能,并且需要访问 ioctl。由于使用 ioctls 的应用程序需要 root 权限才能运行,我能够调用它们的唯一方法是链接一个单独的可执行文件并使用
引用这个链接http://stackoverflow.com/questions/8922102/adding-new-ioctls-into-kernel-number-range 我开始知道编码是
我使用/proc/diskstats 来获取读取和写入的扇区数。我想将这个数字转换为字节,所以我寻找扇区大小。我用了How to find floppy\ CD sector size in Linu
我是一名优秀的程序员,十分优秀!