libaio

 

本文围绕aio.c代码为中心,学习涉及到的c语言编程的相关知识点。

libaio源码分析及应用: https://blog.csdn.net/feihe0755/article/details/125319026

 

vim aio.c

#include <libaio.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

static const int MAX_AIO_EVENT_COUNT = 512;

#define CHECK_RET(ret, event) \
if (ret != 0) { \
  printf("%s failed, ret=%d\n", event, ret); \
  return ret; \
}

int main()
{
  int ret = 0;
  printf("aio test start\n");
  struct timespec ts;
  ts.tv_sec = 0;
  ts.tv_nsec = 1000L * 1000L * 1000L;
  io_context_t *aio_ctx = (io_context_t *)malloc((sizeof(io_context_t)));
  memset(aio_ctx, 0, sizeof(io_context_t));
  struct io_event *aio_events = (struct io_event *)malloc(sizeof(struct io_event) * MAX_AIO_EVENT_COUNT);
  memset(aio_events, 0, sizeof(struct io_event) * MAX_AIO_EVENT_COUNT);

  ret = io_setup(MAX_AIO_EVENT_COUNT, aio_ctx);
  CHECK_RET(ret, "io_setup");

  ret = io_getevents(*aio_ctx, 1, MAX_AIO_EVENT_COUNT, aio_events, &ts);
  CHECK_RET(ret, "io_getevents");

  ret = io_destroy(*aio_ctx);
  CHECK_RET(ret, "io_destroy");

  printf("aio test finished, ret=%d\n", ret);
  return ret;
}

 

【复现步骤】

1、安装依赖 yum install libaio-devel -y

2、编译 gcc aio.c -laio

3、执行程序 ./a.out

【结果】

io_getevents failed ,ret=-22

【期望结果】

io_getevents successful。

 

 

https://blog.csdn.net/naipeng/article/details/89918482

 https://oxnz.github.io/2016/10/13/linux-aio/

1 liaio介绍

linux kernel 提供了5个系统调用来实现异步IO。文中最后介绍的是包装了这些系统调用的用户空间的函数。

2 libaio系统调用

AIO系统调用总共五个,后面会一一介绍。

int io_setup(unsigned nr_events,  aio_context_t *ctxp);
int io_destroy(aio_context_t ctx);
int io_submit(aio_context_t ctx,  long nr,  struct iocb *cbp[]);
int io_cancel(aio_context_t ctx,  struct iocb *,  struct io_event *result);
int io_getevents(aio_context_t ctx, long min_nr, long nr, struct io_event *events, struct timespec *timeout);
 
io_setup - 创建一个异步I / O的上下文
//更多请阅读:https://www.yiibai.com/unix_system_calls/io_setup.html
io_setup () 创建一个至少能够接收maxevents的异步 I/O 上下文。 ctxp 一定不能指向一个已经存在的 AIO 上下文,并且必须在调用之前初始化为 0。成功创建 AIO 上下文后,  *ctxp 将填充结果句柄。 //更多请阅读:https://www.yiibai.com/unix_system_calls/io_setup.html
 
io_destroy - 销毁异步I / O上下文
//更多请阅读:https://www.yiibai.com/unix_system_calls/io_destroy.html
io_destroy () 从 I/O 上下文列表中删除异步 I/O 上下文,然后将其销毁。 io_destroy () 还可以取消 ctx上任何未完成的异步 I/O 操作 并在完成时阻塞。 //更多请阅读:https://www.yiibai.com/unix_system_calls/io_destroy.html

io_submit - 提交处理异步I/ O模块
long  io_submit  (aio_context_t  ctx_id , long  nr , struct iocb  **iocbpp ); 
io_submit () 将nr 个 I/O 请求块排队等待在 AIO 上下文 ctx_id中进行处理。iocbpp 应该是 nr  AIO 请求块的数组,将提交到上下文ctx_id //更多请阅读:https://www.yiibai.com/unix_system_calls/io_submit.html

#################################################################################

指针:

指针是指向变量的地址
简单的例子分析:

int main()
{
	int a = 3;
	int *b = &a;
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	*b = 10;
	cout << "&a:" << &a << endl;
	cout << "b:" << b << endl;
	system("pause");
}

结果:
a:3
b:00EFFE28
&a:00EFFE28
b:00EFFE28
a:10
分析:
b是a的指针,指向a的地址。(也就是a与b相连,只要修改*b的值,a的值也跟着改动)

#############################################################################
 

struct

 

在c语言中结构体(struct)跟面向对象编程(如java等)里面的类是非常相似的。不过像C++里面对结构体进行了扩展,c++里面的结构体是可以包含方法的,但是C语言里面是不能包含方法(函数)的。

结构是由基本数据类型构成的、并用一个标识符来命名的各种变量的组合。

结构中可以使用不同的数据类型。

1. 结构说明和结构变量定义

在Turbo C中, 结构也是一种数据类型, 可以使用结构变量, 因此, 像其它类型的变量一样, 在使用结构变量时要先对其定义。

定义结构变量的一般格式为:

 struct 结构名 
 { 
      类型  变量名; 
      类型  变量名; 
      ... 
 } 结构变量;

结构名是结构的标识符不是变量名。 类型为五种数据类型(整型、浮点型、字符型、指针型和 无值型)。
构成结构的每一个类型变量称为结构成员, 它象数组的元素一样, 但数组中 元素是以下标来访问的, 而结构是按变量名字来访问成员的。

下面举一个例子来说明怎样定义结构变量。

 struct string 
 { 
      char name[8]; 
      int age; 
      char sex[2]; 
      char depart[20]; 
      float wage1, wage2, wage3, wage4, wage5; 
 } person; 

  

这个例子定义了一个结构名为string的结构变量person, 如果省略变量名 person, 则变成对结构的说明。用已说明的结构名也可定义结构变量。这样定义 时上例变成:

 struct string 
 { 
      char name[8]; 
      int age; 
      char sex[2]; 
      char depart[20]; 
      float wage1, wage2, wage3, wage4, wage5; 
 }; 
 struct string person; 

  

如果需要定义多个具有相同形式的结构变量时用这种方法比较方便, 它先作

结构说明, 再用结构名来定义变量。

例如:

struct string Liming, Liuqi, ...;

  如果省略结构名, 则称之为无名结构, 这种情况常常出现在函数内部, 用这种结构时前面的例子变成:

https://blog.csdn.net/weixin_43115440/article/details/93486050

 

###########################################################

函数 功能 原型

io_setup:创建一个异步IO上下文(io_context_t是一个句柄) int io_setup(int maxevents, io_context_t *ctxp);
io_destroy :销毁一个异步IO上下文(如果有正在进行的异步IO,取消并等待它们完成) int io_destroy(io_context_t ctx);
io_submit :提交异步IO请求 long io_submit(aio_context_t ctx_id, long nr, struct iocb **iocbpp);
io_cancel :取消一个异步IO请求 long io_cancel(aio_context_t ctx_id, struct iocb *iocb, struct io_event *result);
io_getevents:等待并获取异步IO请求的事件(也就是异步请求的处理结果) long io_getevents(aio_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout);

原文链接:https://blog.csdn.net/wq897387/article/details/120828005

 

########################################################################

struct timespec 和 struct timeval

https://www.cnblogs.com/book-gary/p/3716790.html

 

time()提供了秒级的精确度 .

1、头文件 <time.h>
2、函数原型
time_t time(time_t * timer)
函数返回从TC1970-1-1 0:0:0开始到现在的秒数

用time()函数结合其他函数(如:localtime、gmtime、asctime、ctime)可以获得当前系统时间或是标准时间。

如果需要更高的时间精确度,就需要struct timespec 和 struct timeval来处理:

一、struct timespec 定义:

typedef long time_t;
#ifndef _TIMESPEC
#define _TIMESPEC
struct timespec {
time_t tv_sec; // seconds
long tv_nsec; // and nanoseconds
};
#endif
struct timespec有两个成员,一个是秒,一个是纳秒, 所以最高精确度是纳秒。
一般由函数int clock_gettime(clockid_t, struct timespec *)获取特定时钟的时间,常用如下4种时钟:
CLOCK_REALTIME 统当前时间,从1970年1.1日算起
CLOCK_MONOTONIC 系统的启动时间,不能被设置
CLOCK_PROCESS_CPUTIME_ID 本进程运行时间
CLOCK_THREAD_CPUTIME_ID 本线程运行时间
struct tm *localtime(const time_t *clock);  //线程不安全
struct tm* localtime_r( const time_t* timer, struct tm* result );//线程安全
size_t strftime (char* ptr, size_t maxsize, const char* format,const struct tm* timeptr );

 

二、struct timeval 定义:

struct timeval {
time_t tv_sec; // seconds
long tv_usec; // microseconds
};
struct timezone{
int tz_minuteswest; //miniutes west of Greenwich
int tz_dsttime; //type of DST correction
};

struct timeval有两个成员,一个是秒,一个是微秒, 所以最高精确度是微秒。
一般由函数int gettimeofday(struct timeval *tv, struct timezone *tz)获取系统的时间

三、 对照样例:

#include<stdio.h>
#include<time.h>
#include<sys/time.h>

void nowtime_ns()
{
    printf("---------------------------struct timespec---------------------------------------\n"); 
    printf("[time(NULL)]     :     %ld\n", time(NULL)); 
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    printf("clock_gettime : tv_sec=%ld, tv_nsec=%ld\n", ts.tv_sec, ts.tv_nsec);
    
    struct tm t;
    char date_time[64];
    strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", localtime_r(&ts.tv_sec, &t));
    printf("clock_gettime : date_time=%s, tv_nsec=%ld\n", date_time, ts.tv_nsec);
}
void nowtime_us()
{
    printf("---------------------------struct timeval----------------------------------------\n"); 
    printf("[time(NULL)]    :    %ld\n", time(NULL)); 
    struct timeval us;
    gettimeofday(&us,NULL);
    printf("gettimeofday: tv_sec=%ld, tv_usec=%ld\n", us.tv_sec, us.tv_usec);
    
    struct tm t;
    char date_time[64];
    strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", localtime_r(&us.tv_sec, &t));
    printf("gettimeofday: date_time=%s, tv_usec=%ld\n", date_time, us.tv_usec);
}

int main(int argc, char* argv[])
{
    nowtime_ns();
    printf("\n");
    nowtime_us();
    printf("\n");
    return 0;
}

  

nowtime.cpp

执行结果:

$tt
---------------------------struct timespec---------------------------------------
[time(NULL)] : 1400233995
clock_gettime : tv_sec=1400233995, tv_nsec=828222000
clock_gettime : date_time=2014-05-16 17:53:15, tv_nsec=828222000

---------------------------struct timeval----------------------------------------
[time(NULL)] : 1400233995
gettimeofday: tv_sec=1400233995, tv_usec=828342
gettimeofday: date_time=2014-05-16 17:53:15, tv_usec=828342

#########################################################################

malloc()

描述

C 库函数 void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。

声明

下面是 malloc() 函数的声明。

void *malloc(size_t size)

参数

  • size -- 内存块的大小,以字节为单位。

返回值

该函数返回一个指针 ,指向已分配大小的内存。如果请求失败,则返回 NULL。

实例

下面的实例演示了 malloc() 函数的用法。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main()
{
   char *str;
 
   /* 最初的内存分配 */
   str = (char *) malloc(15);
   strcpy(str, "runoob");
   printf("String = %s,  Address = %u\n", str, str);
 
   /* 重新分配内存 */
   str = (char *) realloc(str, 25);
   strcat(str, ".com");
   printf("String = %s,  Address = %u\n", str, str);
 
   free(str);
 
   return(0);
}

  

#######################################################################

“上下文”介绍:

你查不到是因为上下文这个东西不是一个具体的东西,上下文在不同的地方表示不同的含义,要感性理解。

context其实说白了,和文章的上下文是一个意思,在通俗一点,我觉得叫环境更好。

....

林冲大叫一声“啊也!”

....

问:这句话林冲的“啊也”表达了林冲怎样的心里?

答:啊你妈个头啊!

看,一篇文章,给你摘录一段,没前没后,你读不懂,因为有语境,就是语言环境存在,一段话说了什么,要通过上下文(文章的上下文)来推断。

子程序之于程序,进程之于操作系统,甚至app的一屏之于app,都是一个道理。

程序执行了部分到达子程序,子程序要获得结果,要用到程序之前的一些结果(包括但不限于外部变量值,外部对象等等);

app点击一个按钮进入一个新的界面,也要保存你是在哪个屏幕跳过来的等等信息,以便你点击返回的时候能正确跳回,如果不存肯定就无法正确跳回了。

看这些都是上下文的典型例子,理解成环境就可以,(而且上下文虽然叫上下文,但是程序里面一般都只有上文而已,只是叫的好听叫上下文。。进程中断在操作系统中是有上有下的,不过不给题主说了,免得产生新的问题)

作者:付鹏
链接:https://www.zhihu.com/question/26387327/answer/32618592
 

但是通常使用Context来描述有几个特点:

  1. 被传入Context的部分(组件),内部需要频繁的获取Context的data和调用function。对context有很强的依赖,实现建立在context的基础上。
  2. Context会被较为多数部分(组件)所需要,在软件实现部分Context会在某个scene下出现单一实例化,然后被多个部分(组件)实例对象调用。出现局部全局化。
  3. Context会持有很多状态data。
  4. Coder习惯,命名选择困难下的胶合产物。

另外 Context的中文翻译是谁想出来的,站出来我保证不打你。

作者:知乎用户
链接:https://www.zhihu.com/question/26387327/answer/32648096
 
 

#######################################################################

“无符号整型”介绍:

无符号整型和有符号整型的区别就是无符号类型可以存放的正数范围比有符号整型中的范围大一倍,因为有符号类型将最高位储存符号,而无符号类型全都储存数字。

posted @ 2022-11-10 21:26  linuxws  阅读(28)  评论(0)    收藏  举报