Linux 使用ACE Proactor异步复制文件有时会失败,原因是signal34

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示例,其中包含一些用于执行复制文件的更改 // ==========

我尝试使用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_信息,