[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Request For Comments: KThread
From:       Waldo Bastian <bastian () suse ! de>
Date:       1999-09-30 9:11:55
[Download RAW message or body]

Given the recent discussion about multi-threading the following might
be of interest:

Request For Comments: KThread

Why Threads?
============

Within KDE a level of parallelism is reached using two mechanisms:
events and sub-processes. Up till now KDE has not made use of threads.
There are some good reasons for this:
1. Threads are complex to use
2. Most activities can be handled in parallel using either events or
  sub-processes.
3. Thread implementations were not widely available in a portable
  fashion.

The above not withstanding, there is an additional need for a finer
grained paralellism within KDE which can be achieved with threads:
* Processing operations which can take an unpredictable and/or
unbounded amount of time.

For these operations, events or sub-processes are often not well suited.
The processing can theoretically be split in small processing-units and
each processing-unit can be handled during one event. This approach is
taken in the HTML Widget. It is however, not always possible to split
a processing task into smaller tasks. In the case of the HTML widget,
starting and stopping the processing of a chunk of HTML code can actually
take longer than the processing of the chunk itself. Another example
could be the loading a of large JPG image. Although technically possible to
do this in small chunks, the library used for handling JPG does not foresee
in this.

The other approach to achieve paralellism is to use sub-processes. The
best example within KDE for this are our IO-slaves. A seperate process is
however unsuitable for tasks which require an intimate interaction with 
data-structures in the parent process, or who produce large quantities 
of data, e.g. image/multi-media operations.

I think it's therefor safe to conclude that there is a need for a finer
grained form of paralellism which can be achieved with threads.

Goals of KThread
================

I stated three reasons why threads haven't been used widely within KDE.
I have shown that the second reason, "Most activities can be handled in 
parallel using either events or sub-processes.", might be valid, but leaves
a significant group of activities out in the cold. With KThread I want to 
offer finer grained paralellism which addresses the other two points:

* KThread should make threading easy.
* KThread should take care of portability issues.


Interface of KThread
====================
I would like to make the following proposal for a KThread implementation.

[An explanation and some examples follow below: NOT YET FINISHED]

class KThread 
{
public:
  KThread(KThreadWorker *worker);

  /**
   * Returns whether the thread is still active
   */
  bool isRunning();

  /**
   * Terminates thread on the first sequence point.
   * (Almost the same as "suspend(); kill();")
   */ 
  void cancel();

  /**
   * Terminates a thread unconditionally.
   * You better know what you are doing.
   */
  void kill();

  /**
   * Suspends thread when it reaches the next sequence point.
   */
  void suspend();

  /**
   * Resumes the thread after it has been suspended.
   */
  void resume();

signals:
  /**
   * Signal indicating the "progress scale".
   */
  void maxProgress(int _maxProgress);

  /**
   * Signal indicating progress
   */
  void progress(int _progress);

  /**
   * Signal containing some info message
   */
  void info(QString infoMsg);

  /**
   * Signal indicating the thread has finished. (See also isRunning())
   */
  void finished();
}

class KThreadWorker
{
   /**
    * Constructor.
    *
    * The constructor is called from the main-thread.
    */
   KThreadWorker();

   /**
    * Destructor.
    *
    * The destructor is called from the main-thread.
    */
   virtual ~KThreadWorker();

   /**
    * Function which does the actual work.
    * Returning from this function terminates the thread.
    */
   virtual void exec() { }; 

   /**
    * Function which gets called before a thread is canceled.
    * This function gets called in the thread itself.
    *
    * Either 'finished()' or 'canceled()' is called but
    * never both of them.
    */
   virtual void canceled() { };

   /**
    * Function which gets called before a thread ends.
    * This function gets called in the thread itself.
    *
    * Either 'finished()' or 'canceled()' is called but
    * never both of them.
    */
   virtual void finsished() { };

   /**
    * Function who indicates a sequence point.
    * The main-thread can suspend() the thread at this point.
    * Normally the object should make sure to be in
    * a defined state when entering this state.
    *
    * This function returns very fast when no suspend() is
    * pending.
    */
   void sequencePoint();

   /**
    * Sends a maxProgress signal to the main-thread. 
    * 
    * The thread gets suspended until the signal has been
    * handled by the main-thread.
    *
    * (Synchronizes with main-thread)
    **/
   void maxProgress(int _maxProgress);

   /**
    * Sends a progress signal to the main-thread. 
    * 
    * The thread gets suspended until the signal has been
    * handled by the main-thread.
    *
    * (Synchronizes with main-thread)
    **/
   void progress(int _progress);

   /**
    * Sends a info signal to the main-thread. 
    * 
    * The thread gets suspended until the signal has been
    * handled by the main-thread.
    *
    * (Synchronizes with main-thread)
    **/
   void info(QString infoMsg);

   /**
    * Sends an event in the application main-loop. 
    * 
    * The thread gets suspended until the event has been
    * handled by the main-thread.
    *
    * (Synchronizes with main-thread)
    **/
   void sendEvent(QObject *receiver, QEvent *ev);
}

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic