我们的系统需要接受来自终端的用户输入并匹配一些已知的关键字字符串(可能是10).
我们没有空间/ computrons来做regexp等,代码需要很小和快速.
现在,令人讨厌的方法是:
// str is null-terminated, assume we know it's safe/sane here
if(!strncmp(str,"hello",5)
{
do_hello();
}
else if(!strncmp(str,"world",5)
{
do_world();
}
else
{
meh(); // Wasn't a match
}
Run Code Online (Sandbox Code Playgroud)
因此,经过一些谷歌搜索和阅读后,我确信更好的方法是将各种匹配的哈希值预先计算为int,然后只使用case语句:
// Assume hash() stops at NULL
switch(hash(str))
{
case HASH_OF_HELLO:
do_hello();
break;
case HASH_OF_WORLD:
do_world();
break;
default:
meh();
break;
}
Run Code Online (Sandbox Code Playgroud)
我们可以在编译时计算*HASH_OF_match*.这似乎是一种从相对较小的集合中选择字符串的更快/更优雅的方式.
那么 - 这看起来合情合理吗?这样做有明显的问题吗?/任何人都有更优雅的方式吗?
作为一个脚注,这是我今天下午看到的最好看的哈希算法;),归功于丹·伯恩斯坦,它看起来就像手头的工作.
unsigned int
get_hash(const char* s)
{
unsigned int hash = 0;
int c;
while((c = *s++))
{
// hash = hash * 33 …Run Code Online (Sandbox Code Playgroud) 对不起,如果标题有点歪斜,我想不出有关我的内容的简明解释!
无论如何,我们有一个嵌入式系统,可将其设置数据存储在一个小型SPI EEPROM/Flash芯片中.在一个非常基本的形式中,它是一个包含设置数据的结构,简化版本可能如下所示:
struct settings_data
{
struct factory_data
{ // Data set at the factory
uint32 serial_number;
uint32 calibration;
};
struct user_data
{ // User-configured data follows:
uint8 user_data_1;
uint8 user_data_2;
char[10] somestring;
// etc...
};
}
Run Code Online (Sandbox Code Playgroud)
一切都很好,直到我们需要在_factory_data_中加上一个额外的值,此时它会移动一切.
现在,有很多方法可以解决这个问题,但是这个问题并不是要找到一个不同的方法,而是关于这个想法是否合理来填充数据结构以便在添加内容时它们不会移动:
struct settings_data
{
union factory_union
{
uint8 padding[100]; // Effectively reserve 100 bytes space
struct factory_data
{ // Data set at the factory
uint32 serial_number;
uint32 calibration;
};
};
union user_union
{
uint8 padding[100]; // …Run Code Online (Sandbox Code Playgroud) 我们正在开发一个嵌入式Linux系统,使用Live555 WIS-Streamer通过网络在RTSP上传输视频.
在一个特定的系统中,我们看到WIS-Streamer卡在TASK_UNINTERRUPTIBLE状态; 从命令行:ps进程的状态显示为DW,WIS进程的子进程都列为Zombie状态.
一旦我们处于这种状态,看起来我们无能为力,除了重启(不可取).但是,我们真的很想找到这个的根本原因 - 我怀疑在流send媒体中它挂在一个阻塞的电话或者某些东西上.有什么我们可以做的,无论是在代码中还是通过命令行等来尝试缩小被阻止的内容?
作为一个例子,我已经尝试查看netstat(netstat -alp)的输出,看看是否有悬挂套接字附加到被阻塞/僵尸线程的PID,但无济于事.
更新更多信息:
它不会破坏CPU,top将阻塞和僵尸线程列为0%mem/0%CPU/VSZ 0.
我尝试过关于系统的其他事情:
/ proc/status/for main&child threads 546是父级,被阻止:
$> cat /proc/546/stat
Name: wis-streamer
State: D (disk sleep)
Tgid: 546
Pid: 546
PPid: 1
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 0
Groups:
Threads: 1
SigQ: 17/353
SigPnd: 0000000000000000
ShdPnd: 0000000000004102
SigBlk: 0000000000000000
SigIgn: 0000000000001004
SigCgt: 0000000180006a02
CapInh: 0000000000000000
CapPrm: ffffffffffffffff
CapEff: ffffffffffffffff …Run Code Online (Sandbox Code Playgroud) 在我们的代码中,我们有一个混合类型的大结构,并希望为这些存储默认值的重复(const)结构.
当用户想要默认设置时,能够通过在结构中获取项的地址偏移量来实现这一点,然后在"defaults"结构中分配具有相同偏移量的值,这样会很好像这样:
void *setting = &settings->thing; // Points to a setting
int offset = setting - &settings;
void *default = &defaults_struct + offset; // Points to the default value
*setting = *default; // Set setting to default value
Run Code Online (Sandbox Code Playgroud)
想法是如果settings-> thing指向int8,则从默认值复制int8值,但如果settings-> other_thing是int32,则复制完整的32位.
问题是,如上所述,这是否适用于无效指针?如果没有,有没有办法做到这一点?我错过了更好的实现方法吗?
编辑澄清:我们希望在结构中将单个值设置为"defaults"结构中的相应值.