首页 \ 问答 \ 继承,后台线程和RAII(Inheritance, background thread and RAII)

继承,后台线程和RAII(Inheritance, background thread and RAII)

我有一个可以启动后台线程的基类,并在需要时停止它。 该线程调用两个虚方法Open()Close() 。 所以所有继承的类都可以重新实现这些方法,但不能启动/停止线程例程(比例子更难)。 我想遵循RAII原则并在基类的构造函数/析构函数中启动/停止该线程。

问题是,在构造函数/析构函数中调用虚方法是一种不好的做法,在我的情况下不起作用。 这是我的问题的一个例子:

#include <iostream>
#include <thread>
#include <atomic>

class Base {
public:
  Base() {
    bg_thread_ = std::thread([this] {
      Open();
      while(!is_stop_) {
      // do stuff
      }
      Close();
    });
  }
  ~Base() {
    is_stop_ = true;
    if(bg_thread_.joinable()) {
      bg_thread_.join();
    }
  }
private:
  virtual void Open() {
    std::cout << "Base open" << std::endl;
  }
  virtual void Close() {
    std::cout << "Base close" << std::endl;
  }
  std::thread bg_thread_;
  std::atomic<bool> is_stop_{false};
};

class Inherited : public Base {
  virtual void Open() override {
    std::cout << "Inherited open" << std::endl;
 }
  virtual void Close() override {
    std::cout << "Inherited close" << std::endl;
 }
};

int main() {
  Inherited inherited;
  std::this_thread::sleep_for(std::chrono::seconds(1));
  return 0;
}

输出是:

Inherited open
Base close

没有睡觉的是:

Base open
Base close

我目前的方法是在构造函数之后调用Start()方法,在析构函数之前调用Stop() ,但我想要使用RAII解决方案。

void Start() {
  bg_thread_ = std::thread([this] {
    Open();
    while(!is_stop_) {
    // do stuff
    }
    Close();
  });
}

void Stop() {
  is_stop_ = true;
  if(bg_thread_.joinable()) {
    bg_thread_.join();
  }
}

I have a base class that can start background thread, and stop it when needed. That thread calls two virtual methods Open() and Close(). So all inherited classes can re-implement this methods, but not starting/stoping thread routine (it more difficult than in example). I want to follow RAII principle and start/stop thid thread in constructor/destructor of base class.

The problem is, that calling virtual methods in constructor/destructor is a bad practice and didn't work in my case. Here is a shot example of my problem:

#include <iostream>
#include <thread>
#include <atomic>

class Base {
public:
  Base() {
    bg_thread_ = std::thread([this] {
      Open();
      while(!is_stop_) {
      // do stuff
      }
      Close();
    });
  }
  ~Base() {
    is_stop_ = true;
    if(bg_thread_.joinable()) {
      bg_thread_.join();
    }
  }
private:
  virtual void Open() {
    std::cout << "Base open" << std::endl;
  }
  virtual void Close() {
    std::cout << "Base close" << std::endl;
  }
  std::thread bg_thread_;
  std::atomic<bool> is_stop_{false};
};

class Inherited : public Base {
  virtual void Open() override {
    std::cout << "Inherited open" << std::endl;
 }
  virtual void Close() override {
    std::cout << "Inherited close" << std::endl;
 }
};

int main() {
  Inherited inherited;
  std::this_thread::sleep_for(std::chrono::seconds(1));
  return 0;
}

The output is:

Inherited open
Base close

And without sleep is:

Base open
Base close

My current approach is to call Start() method after constructor and Stop() before destructor, but I want solution with RAII.

void Start() {
  bg_thread_ = std::thread([this] {
    Open();
    while(!is_stop_) {
    // do stuff
    }
    Close();
  });
}

void Stop() {
  is_stop_ = true;
  if(bg_thread_.joinable()) {
    bg_thread_.join();
  }
}

原文:https://stackoverflow.com/questions/45160814
更新时间:2023-08-06 12:08

最满意答案

就个人而言,我会使用DOMDocument不是SimpleXML ,因为它更容易使用而没有所有的魔力。 但实际上他们可以做同样的事情来满足你的需求。

您要做的是使所有Column节点获取其列名(即Collections属性)并将它们放入列表中。

然后,您需要通过从各自的Column父节点构建Row节点的转置矩阵来获取表的所有行。

这是一个如何做到这一点的简单例子。

$dom = new DOMDocument;
$dom->load($xmlFileName); // load the XML into the DOM

// get all column names
$columnNames = [];
$columns = $dom->getElementsByTagName('Column');
foreach($columns as $column) {
  $columnNames[] = $column->getAttribute("Collections");
}

// get all rows by column [i.e. cells]
$rows = [];
foreach($columns as $c => $column) {
  foreach($column->getElementsByTagName('Row') as $r => $row) {
    $rows[$r][$c] = $row->nodeValue;
  }
}

打印出HTML

现在您可以像这样打印出HTML表格。

// print out the HTML table
echo "<table>";

echo "<thead>";
echo "<tr>";
foreach($columnNames as $columnName) { // the thead
  echo "<th>$columnName</th>";
}
echo "</tr>";
echo "</thead>";
echo "<tbody>";
foreach($rows as $row) { // the tbody
  echo "<tr>";
  foreach($row as $column) {
    echo "<td>$column</td>";
  }
  echo "</tr>";
}
echo "</tbody>";

echo "</table>";

Personally, I would use DOMDocument over SimpleXML, as it's easier to use without all the magic. But effectively they can both do the same thing to meet your needs here.

What you're trying to do is take all of the Column nodes to get their column names (i.e. the Collections attribute) and put them in a list.

Then you need to get all the rows of the table by building a transposed matrix of the Row nodes from their respective Column parent nodes.

Here's a simple example of how to do that.

$dom = new DOMDocument;
$dom->load($xmlFileName); // load the XML into the DOM

// get all column names
$columnNames = [];
$columns = $dom->getElementsByTagName('Column');
foreach($columns as $column) {
  $columnNames[] = $column->getAttribute("Collections");
}

// get all rows by column [i.e. cells]
$rows = [];
foreach($columns as $c => $column) {
  foreach($column->getElementsByTagName('Row') as $r => $row) {
    $rows[$r][$c] = $row->nodeValue;
  }
}

Printing out the HTML

Now you can just print out the HTML table like this.

// print out the HTML table
echo "<table>";

echo "<thead>";
echo "<tr>";
foreach($columnNames as $columnName) { // the thead
  echo "<th>$columnName</th>";
}
echo "</tr>";
echo "</thead>";
echo "<tbody>";
foreach($rows as $row) { // the tbody
  echo "<tr>";
  foreach($row as $column) {
    echo "<td>$column</td>";
  }
  echo "</tr>";
}
echo "</tbody>";

echo "</table>";

相关问答

更多
  • @simplexml_load_file($doc); 这是你的问题所在。 这不会执行xml.php ,但会尝试将该文件(即您编写的PHP代码)解析为XML。 显然(因为它不是XML),这是行不通的。 你必须找到一种从执行xml.php到parse.php的输出。 这样做的简单方法是将所有echo调用改为$xml .= calls,并简单地include xml.php include到parse.php 。 // xml.php $xml = ''; $xml .= "
  • 只有两个PHP API非常适合处理大文件。 第一个是旧的expat api,第二个是较新的XMLreader函数。 这些apis读取连续流,而不是将整个树加载到内存中(这是simplexml和DOM所做的)。 例如,您可能需要查看DMOZ目录的这个部分解析器:
  • 不要重新发明轮子 - 例如,你可以使用Magpie RSS库 PHP。 您可以使用从rdf源加载的数据来更新数据库。 Used simplexml. Had trouble getting Magpie to work. Simplexml was...simple!:)
  • $url = "http://www.opencellid.org/cell/get?key=myapikey&mcc=250&mnc=99&cellid=29513&lac=0"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($ch); $ ...
  • XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); xPathExpression = xpath.compile("//family[text()='Rest1']/e"); NodeList list = (NodeList) xPathExpression .evaluate(xml, XPathConstants.NODESET); 在XP ...
  • 就个人而言,我会使用DOMDocument不是SimpleXML ,因为它更容易使用而没有所有的魔力。 但实际上他们可以做同样的事情来满足你的需求。 您要做的是使所有Column节点获取其列名(即Collections属性)并将它们放入列表中。 然后,您需要通过从各自的Column父节点构建Row节点的转置矩阵来获取表的所有行。 这是一个如何做到这一点的简单例子。 $dom = new DOMDocument; $dom->load($xmlFileName); // load the XML into t ...
  • 仅使用simplexml: $xml = simplexml_load_file("INT.xml"); foreach($xml->{"files.index"}->file as $file) { $id = (string)$file["Product_ID"]; //access attribute $upcs = array(); foreach($file->EAN_UPCS->EAN_UPC as $upc){ //access all child elements ...
  • 你的simpleXML根是ItemLookupResponse所以改变 echo $xml->ItemLookupResponse[0]->Offers->TotalOffers . "
    "; 成 echo $xml->Items->Item->Offers->TotalOffers . "
    "; Your simpleXML root is ItemLookupResponse so change echo $xml->ItemLookupResponse[0]->Offers->Tota ...
  • 我并不完全清楚你想要实现的目标,但这里有一个基本的例子,可以在XML中获取每个源的mount和artist: function sources(){ foreach($this->xml->source as $source) { echo "Mount: " . $source->attributes()['mount'] . '
    '; echo "Artist: " . $source->artist . '
    '; } } 或者找到艺术家的来 ...
  • 这里有几个指针.. 要下载文件并保存,我发现的最简单的方法是:

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。