菜鸟求助一个简单问题

xiaolei1982 2015-04-01 10:35:02
最近看swoole代码发现一个问题

read(event->fd, &task, sizeof(task)
类似这样的直接读取一个struct大小,如何保证大小正合适,按理说这是个不严密的写法,但是作者不会视而不见,
这样写应该是有考虑吧,我是百思不得其解,不知道谁能解答一下


感谢
...全文
212 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
一根烂笔头 2015-04-01
  • 打赏
  • 举报
回复
引用 3 楼 xiaolei1982 的回复:
[quote=引用 1 楼 a30037338 的回复:] 这个取决于你需要读取多少数据啊, 可以是一个结构体,也可以是一个数组。。
但是这个是二进制流,还有信号中断等处理,未必可以一次拿到啊[/quote] 如果被信号中断,会设置设置errno值为EINTR,你需要每次read后测定erron值以确定后续的操作。 像这样

again:
if ((n = read(fd, buf, BUFFSIZE)) < 0) {
if (errno == EINTR)
goto again;
/* just an interrupted system call */
/* handle other errors */
}
不同的系统有不同的设置,有些系统(比如BSD)把read系统调用被信号中断后自动重启,而不用显式处理EINTR;有些系统需要用户设置此行为属性。
一根烂笔头 2015-04-01
  • 打赏
  • 举报
回复
引用 3 楼 xiaolei1982 的回复:
[quote=引用 1 楼 a30037338 的回复:] 这个取决于你需要读取多少数据啊, 可以是一个结构体,也可以是一个数组。。
但是这个是二进制流,还有信号中断等处理,未必可以一次拿到啊[/quote] Linux/Unix一切皆文件,不区分二进制还是文本流
xiaolei1982 2015-04-01
  • 打赏
  • 举报
回复
引用 1 楼 a30037338 的回复:
这个取决于你需要读取多少数据啊, 可以是一个结构体,也可以是一个数组。。
但是这个是二进制流,还有信号中断等处理,未必可以一次拿到啊
赵4老师 2015-04-01
  • 打赏
  • 举报
回复
仅供参考:
#include <stdio.h>
#define field_offset(s,f) (int)(&(((struct s *)(0))->f))
struct AD  { int a; char b[13]; double c;};
#pragma pack(push)
#pragma pack(1)
struct A1  { int a; char b[13]; double c;};
#pragma pack(2)
struct A2  { int a; char b[13]; double c;};
#pragma pack(4)
struct A4  { int a; char b[13]; double c;};
#pragma pack(8)
struct A8  { int a; char b[13]; double c;};
#pragma pack(16)
struct A16 { int a; char b[13]; double c;};
#pragma pack(pop)
int main() {
    printf("AD.a %d\n",field_offset(AD,a));
    printf("AD.b %d\n",field_offset(AD,b));
    printf("AD.c %d\n",field_offset(AD,c));
    printf("\n");
    printf("A1.a %d\n",field_offset(A1,a));
    printf("A1.b %d\n",field_offset(A1,b));
    printf("A1.c %d\n",field_offset(A1,c));
    printf("\n");
    printf("A2.a %d\n",field_offset(A2,a));
    printf("A2.b %d\n",field_offset(A2,b));
    printf("A2.c %d\n",field_offset(A2,c));
    printf("\n");
    printf("A4.a %d\n",field_offset(A4,a));
    printf("A4.b %d\n",field_offset(A4,b));
    printf("A4.c %d\n",field_offset(A4,c));
    printf("\n");
    printf("A8.a %d\n",field_offset(A8,a));
    printf("A8.b %d\n",field_offset(A8,b));
    printf("A8.c %d\n",field_offset(A8,c));
    printf("\n");
    printf("A16.a %d\n",field_offset(A16,a));
    printf("A16.b %d\n",field_offset(A16,b));
    printf("A16.c %d\n",field_offset(A16,c));
    printf("\n");
    return 0;
}
//AD.a 0
//AD.b 4
//AD.c 24
//
//A1.a 0
//A1.b 4
//A1.c 17
//
//A2.a 0
//A2.b 4
//A2.c 18
//
//A4.a 0
//A4.b 4
//A4.c 20
//
//A8.a 0
//A8.b 4
//A8.c 24
//
//A16.a 0
//A16.b 4
//A16.c 24
//
//
此后三年 2015-04-01
  • 打赏
  • 举报
回复
这个取决于你需要读取多少数据啊, 可以是一个结构体,也可以是一个数组。。
xiaolei1982 2015-04-01
  • 打赏
  • 举报
回复
引用 5 楼 my_live_123 的回复:
[quote=引用 3 楼 xiaolei1982 的回复:] [quote=引用 1 楼 a30037338 的回复:] 这个取决于你需要读取多少数据啊, 可以是一个结构体,也可以是一个数组。。
但是这个是二进制流,还有信号中断等处理,未必可以一次拿到啊[/quote] 如果被信号中断,会设置设置errno值为EINTR,你需要每次read后测定erron值以确定后续的操作。 像这样

again:
if ((n = read(fd, buf, BUFFSIZE)) < 0) {
if (errno == EINTR)
goto again;
/* just an interrupted system call */
/* handle other errors */
}
不同的系统有不同的设置,有些系统(比如BSD)把read系统调用被信号中断后自动重启,而不用显式处理EINTR;有些系统需要用户设置此行为属性。[/quote] 非常感谢,但是我看的这是现在很出名的swoole的代码,代码里确实就是这样来读取一个结构的,我想应该是有什么作用,要不这么明显的错误,怎么会出现呢?

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧