Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在另一个线程中执行方法? 我在C或C++中寻找解决这个问题的方法。 编辑:澄清。这是在linux系统上实现的。Linux特定的解决方案绝对不错。交叉格子不是一个问题_C++_C_Multithreading_Design Patterns_Class Design - Fatal编程技术网

如何在另一个线程中执行方法? 我在C或C++中寻找解决这个问题的方法。 编辑:澄清。这是在linux系统上实现的。Linux特定的解决方案绝对不错。交叉格子不是一个问题

如何在另一个线程中执行方法? 我在C或C++中寻找解决这个问题的方法。 编辑:澄清。这是在linux系统上实现的。Linux特定的解决方案绝对不错。交叉格子不是一个问题,c++,c,multithreading,design-patterns,class-design,C++,C,Multithreading,Design Patterns,Class Design,我有一个在自己线程中运行的服务。此服务是一个包含多个方法的类,其中一些方法需要在自己的服务线程中运行,而不是在调用方的线程中运行 目前,我正在使用包装器方法创建一个带有输入和输出参数的结构,在队列上插入该结构,然后返回(如果“命令”是异步的)或等待其执行(如果“命令”是同步的) 在线程端,服务唤醒,从队列中弹出一个结构,找出要执行的内容并调用适当的方法 此实现可以工作,但添加新方法相当麻烦:定义包装器、带参数的结构和处理程序。我想知道是否有一种更直接的方法来编码这种模型:在类自己的线程上执行的类

我有一个在自己线程中运行的服务。此服务是一个包含多个方法的类,其中一些方法需要在自己的服务线程中运行,而不是在调用方的线程中运行

目前,我正在使用包装器方法创建一个带有输入和输出参数的结构,在队列上插入该结构,然后返回(如果“命令”是异步的)或等待其执行(如果“命令”是同步的)

在线程端,服务唤醒,从队列中弹出一个结构,找出要执行的内容并调用适当的方法

此实现可以工作,但添加新方法相当麻烦:定义包装器、带参数的结构和处理程序。我想知道是否有一种更直接的方法来编码这种模型:在类自己的线程上执行的类方法,而不是在调用方的线程中执行

编辑-结论类型:
似乎没有一种事实上的方法可以实现我所要求的,而不需要额外的编码工作。
我将坚持我的想法,它确保了类型安全性,最大限度地减少了锁定,允许同步和异步调用,并且开销相当小。

另一方面,它需要一些额外的编码,并且随着方法数量的增加,分派机制可能会变得臃肿。在构造中注册分派方法,或者让包装器完成这项工作,似乎可以解决问题,减少一些开销,还可以删除一些代码。

我对这个问题的标准参考是

使用条件变量实现线程安全队列

正如@John所指出的,它使用Boost.Thread


我会小心你在这里描述的同步案例。如果生产者(发送线程)等待消费者(服务线程)的结果,则很容易出现性能问题。如果您收到1000个异步调用,用积压工作填满队列,然后是来自每个生产者线程的同步调用,会发生什么?您的系统将“装死”,直到队列积压清除,释放这些同步调用者。如果可以的话,尝试仅使用异步将它们解耦。

根据您想要接受的复杂性,有几种方法可以实现这一点。代码的复杂性与所需的灵活性成正比。这里有一个简单的例子(使用得很好):

定义与服务器公开的每个功能相对应的类。 这些类中的每一个都实现一个名为execute的函数,并采用名为input args和output args的基本结构

在服务内部,在初始化时注册这些方法类。 一旦请求到达线程,它将只有两个参数Input和output,这两个参数是不同方法类所需的更专门的参数的基类

然后,您将服务类编写为一个简单的委托,它接受传入的请求,并根据ID或方法名称(在初始注册期间使用)传递给相应的方法类

<希望>是有意义的,这种方法的一个很好的例子是在XMLRPC++中(XMLRPC的C++实现,你可以从SooCoFig获得源代码)。 重述:

struct Input {
  virtual ~Input () = 0;
};

struct Ouput {
  virtual ~Output () = 0;
};

struct MethodInterface {
   virtual int32_t execute (Input* __input, Output* __output)  = 0;
};

// Write specialized method classes and taking specialized input, output classes
class MyService {


  void registerMethod (std::string  __method_name, MethodInterface* __method);
  //external i/f
  int32_t execute (std::string __method, Input* __input, Output* __output);
};

您仍将使用队列机制,但不需要任何包装器。

除了使用Boost.Thread外,我还将介绍Boost::function和Boost::bind。这就是说,将非类型化(void)参数传递给目标方法,并让这些方法转换为正确的类型(这是C#等语言的典型习惯用法)似乎是公平的。

嘿,现在Rajivji,我想你把它颠倒了。代码的复杂性与灵活性成反比。数据结构和算法越复杂,对可接受的输入和行为的限制就越多

对于OP:您的描述似乎非常笼统,而且是唯一的解决方案,尽管它有不同的编码。最简单的方法可能是从以下内容派生类:

struct Xqt { virtual void xqt(){} virtual ~Xqt(){} }; 结构Xqt{virtual void Xqt(){}virtual~Xqt(){}; 然后有一个指向Xqt的线程安全的指针队列。然后服务线程将队列弹出到px并调用px->xqt(),然后删除px。最重要的派生类是:

struct Dxqt : Xqt { xqt *delegate; Dxqt(xqt *d) : delegate(d) {} void xqt() { delegate->xqt(); } }; 结构Dxqt:Xqt{ xqt*代表; Dxqt(xqt*d):委托(d){ void xqt(){delegate->xqt();} };
因为“计算机科学中的所有问题都可以通过一个更高的间接层次来解决”,特别是这个类不会删除委托。例如,这比使用标志来确定服务器线程是否应该删除closure对象要好得多。

IMHO,如果要将方法执行和线程上下文解耦,应该使用活动对象模式(AOP)

但是,您需要使用ACE Framework,它支持许多操作系统,例如Windows、Linux、VxWorks

你可以找到详细的信息


此外,AOP是命令、代理和观察者模式的组合,如果您知道它们的详细信息,您可以实现自己的AOP。希望对您有所帮助

您可以使用Boost.Thread获得与平台无关的建议,但是什么平台?这是linux上的。它不需要跨平台。您能否格式化代码,使其更易于理解和阅读?谢谢你的解决方案看起来有点像我现在正在做的。我必须为每个方法/功能编写一个包装类,并为从外部调用该功能编写一个方法。还是我误解了答案?boost::bind可以将函数与参数结合起来,但您仍然需要一些(多态性?)调度,因为编译器无法决定其他线程必须调用什么。这需要的代码比我使用的代码少一点