Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute a method in another thread?

I'm looking for a solution for this problem in C or C++.
edit: To clarify. This is on a linux system. Linux-specific solutions are absolutely fine. Cross-plaform is not a concern.

I have a service that runs in its own thread. This service is a class with several methods, some of which need to run in the own service's thread rather than in the caller's thread.

Currently I'm using wrapper methods that create a structure with input and output parameters, insert the structure on a queue and either return (if a "command" is asynchronous) or wait for its execution (if a "command" is synchronous).

On the thread side, the service wakes, pops a structure from the queue, figures out what to execute and calls the appropriate method.

This implementation works but adding new methods is quite cumbersome: define wrapper, structure with parameters, and handler. I was wondering if there is a more straightforward means of coding this kind of model: a class method that executes on the class's own thread, instead of in the caller's thread.

edit - kind of conclusion:
It seems that there's no de facto way to implement what I asked that doesn't involve extra coding effort.
I'll stick with what I came up with, it ensures type safeness, minimizes locking, allows sync and async calls and the overhead it fairly modest.
On the other hand it requires a bit of extra coding and the dispatch mechanism may become bloated as the number of methods increases. Registering the dispatch methods on construction, or having the wrappers do that work seem to solve the issue, remove a bit of overhead and also remove some code.

like image 713
amso Avatar asked Nov 24 '10 16:11

amso


People also ask

How do you run a method in a new thread?

Java Thread run() methodThe run() method of thread class is called if the thread was constructed using a separate Runnable object otherwise this method does nothing and returns. When the run() method calls, the code specified in the run() method is executed. You can call the run() method multiple times.

Can we call run method directly in thread?

No, you can not directly call run method to start a thread. You need to call start method to create a new thread. If you call run method directly , it won't create a new thread and it will be in same stack as main.

How do you run a thread method in Java?

We can call the run() method multiple times. The run() method can be called in two ways which are as follows: Using the start() method. Using the run() method itself.


2 Answers

My standard reference for this problem is here.

Implementing a Thread-Safe Queue using Condition Variables

As @John noted, this uses Boost.Thread.

I'd be careful about the synchronous case you described here. It's easy to get perf problems if the producer (the sending thread) waits for a result from the consumer (the service thread). What happens if you get 1000 async calls, filling up the queue with a backlog, followed by a sync call from each of your producer threads? Your system will 'play dead' until the queue backlog clears, freeing up those sync callers. Try to decouple them using async only, if you can.

like image 172
Steve Townsend Avatar answered Oct 25 '22 21:10

Steve Townsend


There are several ways to achieve this, depending upon the complexity you want to accept. Complexity of the code is directly proportional to the flexibility desired. Here's a simple one (and quite well used):

Define a classes corresponding to each functionality your server exposes. Each of these classes implements a function called execute and take a basic structure called input args and output args.

Inside the service register these methods classes at the time of initialization. Once a request comes to the thread, it will have only two args, Input and Ouput, Which are the base classes for more specialized arguments, required by different method classes.

Then you write you service class as mere delegation which takes the incoming request and passes on to the respective method class based on ID or the name of the method (used during initial registration).

I hope it make sense, a very good example of this approach is in the XmlRpc++ (a c++ implementation of XmlRpc, you can get the source code from sourceforge).

To recap:

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);
};

You will still be using the queue mechanism, but you won't need any wrappers.

like image 22
Rajivji Avatar answered Oct 25 '22 20:10

Rajivji