Linux 使用ACE Proactor异步复制文件有时会失败,原因是signal34
我尝试使用ACE框架异步复制文件,读取62K块,在读取回调时开始写入此块,然后开始下一次读取。 我一块一块地做这件事,因为除了复制之外,我还喜欢处理读取的数据。 在这个示例中,有时程序因信号34而失败(将此代码添加到大型程序中,在第一次句柄读取文件调用时,它总是因信号34而失败)。为什么?我怎样才能解决这个问题 ACE在Linux上使用posix异步io。 我在CentOs 7.8或red hat 8上运行此程序 此代码是ACE示例,其中包含一些用于执行复制文件的更改Linux 使用ACE Proactor异步复制文件有时会失败,原因是signal34,linux,asynchronous,centos,posix,ace,Linux,Asynchronous,Centos,Posix,Ace,我尝试使用ACE框架异步复制文件,读取62K块,在读取回调时开始写入此块,然后开始下一次读取。 我一块一块地做这件事,因为除了复制之外,我还喜欢处理读取的数据。 在这个示例中,有时程序因信号34而失败(将此代码添加到大型程序中,在第一次句柄读取文件调用时,它总是因信号34而失败)。为什么?我怎样才能解决这个问题 ACE在Linux上使用posix异步io。 我在CentOs 7.8或red hat 8上运行此程序 此代码是ACE示例,其中包含一些用于执行复制文件的更改 // ==========
// ============================================================================
/**
* @file Proactor_File_Test.cpp
*
* This program illustrates how the ACE_Proactor can be used to
* implement an application that does asynchronous file IO
* operations.
*
* @author Martin Corino <mcorino@remedy.nl>
*/
// ============================================================================
#include "test_config.h"
#if defined (ACE_HAS_AIO_CALLS)
#include <stdio.h>
#include "ace/OS_NS_stdio.h"
#include "ace/OS_NS_unistd.h"
#include "ace/OS_NS_errno.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_sys_time.h"
#include "ace/FILE_Connector.h"
#include "ace/FILE_IO.h"
#include "ace/Proactor.h"
#include "ace/Asynch_Connector.h"
#include "ace/Time_Value.h"
#include "ace/Task.h"
#include "ace/POSIX_Proactor.h"
#define FILE_FRAME_SIZE 62*1024
class FileIOHandler : public ACE_Handler
{
public:
FileIOHandler ();
virtual ~FileIOHandler ();
int file_size= 0;
int
Connect();
// This method will be called when an asynchronous read
// completes on a file.
virtual void
handle_read_file(const ACE_Asynch_Read_File::Result &result);
// This method will be called when an asynchronous write
// completes on a file.
virtual void
handle_write_file(const ACE_Asynch_Write_File::Result &result);
template<typename OBJ >
class Operation
{
public:
OBJ obj;
};
// Our I/O objects;
Operation<ACE_Asynch_Read_File> reader_;
Operation<ACE_Asynch_Write_File> writer_;
private:
int block_count_;
ACE_FILE_IO peer_;
ACE_FILE_Connector connector_;
};
FileIOHandler::FileIOHandler ()
: ACE_Handler ()
, block_count_ (0)
{
}
FileIOHandler::~FileIOHandler ()
{
}
//***************************************************************************
// Method: Connect
//
// Description: Establishes connection, primes read process
//***************************************************************************
int FileIOHandler::Connect()
{
int result = 0;
// get file address
ACE_FILE_Addr tmp_addr(ACE_TEXT("YANIV_SOURCE"));
// reopen new file for asynch IO
if(connector_.connect(peer_,
tmp_addr,
0, //timeout
ACE_Addr::sap_any,
0, //reuse
O_RDWR |FILE_FLAG_OVERLAPPED) != 0)
{
ACE_ERROR((LM_ERROR, ACE_TEXT("%p\n"),
ACE_TEXT("FileIOHandler connect failed to open file")));
peer_.remove ();
result = -1;
}
else // device connected successfully
{
// keep track of our writes for offset calculations
this->block_count_ = 0; // start counting
file_size = ACE_OS::filesize(peer_.get_handle());
if (writer_.obj.open(*this, ACE_OS::open("Yaniv_Destination", O_RDWR | O_CREAT)) != 0 || reader_.obj.open(*this, peer_.get_handle()) != 0)
{
ACE_ERROR(
(LM_ERROR, ACE_TEXT("%p\n"), ACE_TEXT("FileIOHandler reader or writer open failed")));
result = -1;
}
else // reader and writer opened successfully
{
// Allocate a new message block and initiate a read operation on it
// to prime the asynchronous read pipeline
// The message block is sized for the largest message we expect
ACE_Message_Block *mb;
ACE_NEW_NORETURN(mb, ACE_Message_Block(FILE_FRAME_SIZE));
if (reader_.obj.read(*mb, mb->space()) != 0)
{
int errnr = ACE_OS::last_error ();
ACE_DEBUG(
(LM_INFO, ACE_TEXT("%p [%d]\n"), ACE_TEXT("FileIOHandler begin read failed"), errnr));
mb->release();
result = -1;
}
// If read worked, psMsg is now controlled by Proactor framework.
}
}
return result;
}
//***************************************************************************
//
// Method: handle_read_file
//
// Description: Callback used when a read completes
//
// Inputs: read file result structure containing message block
//
// Returns: none
//
//***************************************************************************
void
FileIOHandler::handle_read_file(const ACE_Asynch_Read_File::Result &result)
{
ACE_Message_Block &mb = result.message_block();
// If the read failed, queue up another one using the same message block
if (!result.success() || result.bytes_transferred() == 0)
{
ACE_DEBUG((LM_INFO, ACE_TEXT("///////////////////////Error//////////////////////////////////////////\n")));
}
else
{
// enqueue mb to some queueue for some process parallel to write( on the next row).
// queue up a write (append to end of file) operation, give visual feedback on success or failure.
if (this->writer_.obj.write(mb, mb.length(), this->block_count_ * FILE_FRAME_SIZE) == 0)
{
this->block_count_ ++; // next block
}
else
{
ACE_DEBUG((LM_ERROR, ACE_TEXT("FAILED to queue write operation\n"))); // failure
};
if ((result.offset () + result.bytes_transferred ()) < file_size)
{
// Our processing is done; prime the read process again
ACE_Message_Block *new_mb;
ACE_NEW_NORETURN(new_mb, ACE_Message_Block(FILE_FRAME_SIZE));
if (reader_.obj.read(*new_mb, new_mb->space(),
result.offset () + result.bytes_transferred ()) != 0)
{
int errnr = ACE_OS::last_error ();
ACE_DEBUG(
(LM_INFO, ACE_TEXT("%p [%d]\n"), ACE_TEXT("FileIOHandler continuing read failed"), errnr));
new_mb->release();
}
}
}
}
//***************************************************************************
//
// Method: handle_write_file
//
// Description: Callback used when a write completes
//
// Inputs: write file result structure containing message block
//
// Returns: none
//
//***************************************************************************
void
FileIOHandler::handle_write_file(const ACE_Asynch_Write_File::Result &result)
{
// When the write completes, we get the message block. It's been sent,
// so we just deallocate it.
result.message_block().release();
if ((result.offset () + result.bytes_transferred ()) == file_size)
{
// we have it all; stop the proactor
ACE_Proactor::instance ()->proactor_end_event_loop ();
}
}
class MyTask: public ACE_Task < ACE_MT_SYNCH >
{
FileIOHandler *fileIOHandler_;
public:
MyTask(FileIOHandler &fileIOHandler)
{
fileIOHandler_ = &fileIOHandler;
activate();
}
int svc()
{
fileIOHandler_->Connect();
return 0;
}
};
int
run_main(int /*argc*/, ACE_TCHAR * /*argv*/[])
{
FileIOHandler fileIOHandler;
MyTask myTask(fileIOHandler);
// Run the Proactor
ACE_Proactor::instance()->proactor_run_event_loop();
ACE_END_TEST;
return 0;
}
#endif /* ACE_HAS_AIO_CALLS */
//============================================================================
/**
*@file Proactor\u file\u Test.cpp
*
*该程序说明了如何使用ACE_Proactor
*实现一个执行异步文件IO的应用程序
*行动。
*
*@作者马丁·科里诺
*/
// ============================================================================
#包括“test_config.h”
#如果已定义(ACE_有_AIO_调用)
#包括
#包括“ace/OS_NS_stdio.h”
#包括“ace/OS\n\u unistd.h”
#包括“ace/OS\n\u errno.h”
#包括“ace/OS\n\u string.h”
#包括“ace/OS\n\u sys\u time.h”
#包括“ace/FILE_Connector.h”
#包括“ace/FILE_IO.h”
#包括“ace/Proactor.h”
#包括“ace/Asynch\u Connector.h”
#包括“ace/Time_值.h”
#包括“ace/Task.h”
#包括“ace/POSIX_Proactor.h”
#定义文件\帧\大小62*1024
类FileIOHandler:公共ACE\U处理程序
{
公众:
FileIOHandler();
virtual~FileIOHandler();
int file_size=0;
int
Connect();
//异步读取时将调用此方法
//在文件上完成。
虚空
handle_read_file(const ACE_Asynch_read_file::Result&Result);
//异步写入时将调用此方法
//在文件上完成。
虚空
handle_write_file(const ACE_Asynch_write_file::Result&Result);
模板
班级作业
{
公众:
OBJ-OBJ;
};
//我们的I/O对象;
操作读取器;
操作编写器;
私人:
整块计数;
ACE\u文件\u IO对等\u;
ACE文件连接器连接器连接器;
};
FileIOHandler::FileIOHandler()
:ACE_Handler()
,块计数(0)
{
}
FileIOHandler::~FileIOHandler()
{
}
//***************************************************************************
//方法:连接
//
//描述:建立连接,启动读取过程
//***************************************************************************
int FileIOHandler::Connect()
{
int结果=0;
//获取文件地址
ACE_文件地址tmp_地址(ACE_文本(“YANIV_源”);
//重新打开异步IO的新文件
如果(连接器)连接(对等),
tmp_地址,
0,//超时
ACE_地址::sap_any,
0,//重用
O_RDWR |文件_标志_重叠)!=0)
{
ACE_错误((LM_错误,ACE_文本(“%p\n”),
ACE_TEXT(“FileIOHandler连接无法打开文件”);
peer_.remove();
结果=-1;
}
else//设备已成功连接
{
//跟踪偏移量计算的写入操作
此->块\u计数\u=0;//开始计数
file_size=ACE_OS::filesize(peer_u.get_handle());
if(writer.obj.open(*this,ACE_OS::open(“Yaniv_Destination”,O|RDWR | O|u create))!=0 | | reader|obj.open(*this,peer|get_handle())!=0)
{
ACE_错误(
(LM_错误、ACE_文本(“%p\n”)、ACE_文本(“FileIOHandler读取器或写入器打开失败”);
结果=-1;
}
else//读写器已成功打开
{
//分配一个新的消息块并对其启动读取操作
//初始化异步读取管道
//消息块的大小适合我们期望的最大消息
ACE_消息块*mb;
ACE_NEW_NORETURN(mb,ACE_Message_Block(文件帧大小));
if(reader_uj.obj.read(*mb,mb->space())!=0)
{
int errnr=ACE_OS::last_error();
ACE_调试(
(LM_信息、ACE_文本(“%p[%d]\n”)、ACE_文本(“FileIOHandler开始读取失败”)、errnr);
mb->release();
结果=-1;
}
//如果读取成功,psMsg现在由Proactor框架控制。
}
}
返回结果;
}
//***************************************************************************
//
//方法:处理\u读取\u文件
//
//描述:读取完成时使用的回调
//
//输入:读取包含消息块的文件结果结构
//
//退货:无
//
//***************************************************************************
无效的
FileIOHandler::handle\u read\u file(const ACE\u Asynch\u read\u file::Result和Result)
{
ACE_Message_Block&mb=result.Message_Block();
//如果读取失败,请使用相同的消息块将另一个消息排队
如果(!result.success()| result.bytes_transfer()==0)
{
ACE\U调试((LM\U信息,ACE\U文本(///////Error/////////////n));
}
其他的
{
//将mb排队到某个队列,以便某个进程并行写入(下一行)。
//将写入(追加到文件末尾)操作排队,对成功或失败给出可视化反馈。
如果(this->writer\uu.obj.write(mb,mb.length(),this->block\u count\u*FILE\u FRAME\u SIZE)==0)
{
此->块count++;//下一个块
}
其他的
{
ACE_调试((LM_错误,ACE_文本(“写入操作队列失败”);//失败
};
if((result.offset()+result.bytes\u transfer())<文件大小)
{
//我们的处理完成了;再次启动读取过程
ACE_消息块*new_mb;
ACE_NEW_NORETURN(新_mb,ACE_消息块(文件帧大小));
if(reader_u.obj.read(*new_-mb,new_-mb->space(),
result.offset()+result.bytes_transfer())!=0)
{
int errnr=ACE_OS::last_error();
ACE_调试(
(LM_信息,