您的位置:首页 > 运维架构 > Linux

Linux 异步IO 读写编程

2015-12-22 15:50 627 查看
使用AIO读写文件

编译时需连接以下动态库

LIBS += /usr/lib/x86_64-linux-gnu/librt.so

LIBS += -lpthread

#ifndef CAIO_H
#define CAIO_H
#include <string>
#include <aio.h>
#include <stdio.h>
#include <unistd.h>
#include <aio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
using namespace std;
enum eAIOState
{
eBusyState,
eReadyState
};

typedef void (*FucCallBackAIO)(sigval_t);
class CAIO
{
public:
CAIO();
~CAIO();
bool Open(string strName, int nMode);
bool  Close();
int Write(const char* buf, int nSize, bool bAppend, eAIOState&  eIOState);
int Read(char* buf );
void SetCallbackFuc(FucCallBackAIO  fAIO);
int  GetFileSize(const char *szFileName);
void Seek(int offset, int __whence);
int Write(const char* buf, int nSize);;
int GetFD();
private:
struct aiocb m_aiocb;
int m_fdFile;
string m_strFilename;
int m_nFileSize;
};

#endif // CAIO_H
#include <fcntl.h>
#include <sys/stat.h>
#include "caio.h"
using namespace std;
CAIO::CAIO()
{
m_fdFile =-1;
m_nFileSize=0;
}

CAIO::~CAIO()
{

}

int CAIO::GetFileSize(const char *szFileName)
{
int nSize=0;
struct stat buffer;
int         status;
status = stat(szFileName, &buffer);
if(status>=0)
{
nSize=buffer.st_size;

}
return nSize;
}

bool CAIO::Open(string strName, int nMode)
{
m_fdFile = open(strName.c_str(), nMode);
if(m_fdFile < 0)
{
printf("Open %s failed\n", strName.c_str());
return false;
}

bzero((void*) &m_aiocb, sizeof(struct aiocb));
m_aiocb.aio_fildes = m_fdFile;
m_aiocb.aio_offset =0;
m_nFileSize= GetFileSize(strName.c_str());
m_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD;
//  指定回调函数
m_aiocb.aio_sigevent._sigev_un._sigev_thread._attribute = NULL;
//  指定AIO请求
return true;
}

void CAIO::SetCallbackFuc(FucCallBackAIO  fAIO)
{
m_aiocb.aio_sigevent._sigev_un._sigev_thread._function =fAIO;
m_aiocb.aio_sigevent.sigev_value.sival_ptr = &m_aiocb;
}

int CAIO::Write(const char* buf, int nSize, bool bAppend, eAIOState&  eIOState)
{

m_aiocb.aio_nbytes = nSize;
m_aiocb.aio_buf=(void*)buf;
m_aiocb.aio_offset=0;
m_aiocb.aio_offset+=m_nFileSize;
if(!bAppend)
m_aiocb.aio_offset = 0;
//  发送异步读请求
int ret;
if(eReadyState == eIOState)
{
ret = aio_write(&m_aiocb);
if (ret < 0)
sleep(1);
m_nFileSize +=nSize;
eIOState = eBusyState;
}
return ret;
}

void CAIO::Seek(int offset, int __whence)
{
lseek(m_fdFile, offset, SEEK_SET);
}

int CAIO::Write(const char* buf, int nSize)
{
write(m_fdFile,buf,nSize);
}

int CAIO::GetFD()
{
return m_fdFile;
}

bool CAIO::Close()
{
if (close(m_fdFile) < 0)
{
return false;
}
return true;
}


#include <fcntl.h>
#include <aio.h>
#include  "caio.h"
#include <iostream>
using namespace std;
void msleep( unsigned int ms )
{
int microsecs;
struct timeval tv;
microsecs = ms * 1000;
tv.tv_sec  = microsecs / 1000000;
tv.tv_usec = microsecs % 1000000;
select( 0, NULL, NULL, NULL, &tv );
}

eAIOState  g_eIOState;
void aio_completion_handler( sigval_t sigval )
{
int ret;
struct aiocb *tAiocb;
//  获取aiocb结构体指针
tAiocb = (struct aiocb *)sigval.sival_ptr;
//  获取异步读请求的返回值
if ((ret = aio_return(tAiocb)) > 0)
{
//  获取并输出读取的数据
printf("value:%s\n", (char*) (tAiocb->aio_buf));
g_eIOState = eReadyState;
}
}

#define BUFFER_SIZE 100
//  AIO回调函数
int main()
{
CAIO aio;
bool bOpen= aio.Open("/media/sda1/Videos/20151221/1/155332.mp4",O_WRONLY);
aio.SetCallbackFuc(aio_completion_handler);
if(false == bOpen)
return 1;
string strData="yes tes";
g_eIOState = eReadyState;
for(int i=0 ; i < 10; )
{
if(eReadyState==g_eIOState )
{
aio.Write(strData.c_str(), strData.length(), true, g_eIOState);
i++;
}
msleep(100);
}
aio.Seek(4, 0);
strData="fffff";
msleep(1000);
aio.Write(strData.c_str(), strData.length());
aio.Close();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: