Difference between revisions of "User:Kr/A Thread's Life/Example Code"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (Now creates randomly activities and daemons ...)
Line 1: Line 1:
 
<code>[cpp]
 
<code>[cpp]
 +
//
 +
// gcc -g main.c -o main.bin -lpthread
 +
//
 +
 
#include <stdlib.h>
 
#include <stdlib.h>
 
#include <stdio.h>
 
#include <stdio.h>
 
#include <pthread.h>
 
#include <pthread.h>
 +
#include <string.h>
  
  
static void * holder(void * gr) {
+
typedef struct Daemon  Daemon;
    fprintf(stderr, "%s - tid: %x\n", __PRETTY_FUNCTION__, pthread_self());
+
  
     sleep(5);
+
struct Daemon {
 +
     Daemon * previous_;
 +
    Daemon * next_;
  
 +
    pthread_t hd_;
 +
};
 +
 +
static Daemon        * firstDaemon_  = NULL;
 +
static unsigned    int daemons_      = 0;
 +
static pthread_mutex_t daemons_mutex_ = PTHREAD_MUTEX_INITIALIZER;
 +
 +
static Daemon * new_daemon(void) {
 +
    Daemon * daemon = malloc(sizeof(Daemon));
 
      
 
      
     if (1) // This may only be true if this is the last "holder" thread!
+
    pthread_mutex_lock(&daemons_mutex_);
 +
 
 +
    daemon->previous_ = NULL;
 +
    daemon->next_ = firstDaemon_;
 +
 
 +
     if (firstDaemon_)  
 +
        firstDaemon_->previous_ = daemon;
 +
 
 +
    firstDaemon_ = daemon;
 +
 
 +
    ++ daemons_;
 +
 
 +
    pthread_mutex_unlock(&daemons_mutex_);
 +
 
 +
    return daemon;
 +
}
 +
 
 +
static void end_of_daemon(void * context) {
 +
    Daemon * daemon = (Daemon *)context;
 +
 
 +
    pthread_mutex_lock(&daemons_mutex_);
 +
    -- daemons_;
 +
 
 +
    if (daemon->next_)
 +
        daemon->next_->previous_ = daemon->previous_;
 +
 
 +
    if (daemon->previous_)
 +
        daemon->previous_->next_ = daemon->next_;
 +
 
 +
    if (firstDaemon_ == daemon)
 +
        firstDaemon_ = daemon->next_;
 +
 
 +
    pthread_mutex_unlock(&daemons_mutex_);
 +
 
 +
    free(daemon);
 +
 
 +
    // This thread is not in the list of daemons anymore,
 +
    // and therefor can't be joined.
 +
    pthread_detach(pthread_self());
 +
}
 +
 
 +
static void create_a_daemon(void);
 +
 
 +
static void * daemon_func(void * para) {
 +
    pthread_cleanup_push (end_of_daemon, para);
 +
 
 +
    int n = 10;
 +
    while (n) {
 +
        sleep(1);
 +
       
 +
        if (rand() < (RAND_MAX / (daemons_ + 1)))
 +
            create_a_daemon();
 +
 
 +
        -- n;
 +
    }
 +
 
 +
    pthread_cleanup_pop(1);
 +
 
 +
    return NULL;
 +
}
 +
 
 +
static void join_daemons(void) {
 +
    fprintf(stderr, "%s ... ", __PRETTY_FUNCTION__, pthread_self());
 +
 
 +
    pthread_mutex_lock(&daemons_mutex_);
 +
    while (firstDaemon_) {
 +
        pthread_t hd;
 +
 
 +
        memcpy(&hd, &firstDaemon_->hd_, sizeof(pthread_t));
 +
 
 +
        pthread_mutex_unlock(&daemons_mutex_);
 +
 
 +
        // We may want to cancel a thread actively during termination:
 +
        pthread_cancel(hd);
 +
        // respectively
 +
        //pthread_kill();
 +
 
 +
        pthread_join(hd, NULL);
 +
 
 +
        pthread_mutex_lock(&daemons_mutex_);
 +
    }
 +
    pthread_mutex_unlock(&daemons_mutex_);
 +
 
 +
    fprintf(stderr, "done\n");
 +
}
 +
 
 +
static void create_a_daemon(void) {
 +
    Daemon * daemon = new_daemon();
 +
    pthread_create(&daemon->hd_, NULL, daemon_func, daemon);
 +
}
 +
 
 +
 
 +
static unsigned    int activities_    = 1; // The "main" thread is the first "activity".
 +
static pthread_mutex_t activity_mutex_ = PTHREAD_MUTEX_INITIALIZER;
 +
 
 +
static void new_activity(void) {
 +
    pthread_mutex_lock(&activity_mutex_);
 +
    ++ activities_;
 +
    pthread_mutex_unlock(&activity_mutex_);
 +
}
 +
 
 +
static void end_of_activity(void) {
 +
    int use_exit = 0;
 +
    pthread_mutex_lock(&activity_mutex_);
 +
    -- activities_;
 +
    use_exit = activities_ == 0;
 +
    pthread_mutex_unlock(&activity_mutex_);
 +
 
 +
  // Terminate the process, if this was the last "activity"!
 +
    if (use_exit)
 
         exit(0);
 
         exit(0);
  
Line 18: Line 142:
 
}
 
}
  
static void createHolderThread() {
+
static void create_an_activity(void);
 +
 
 +
static void * activity(void * gr) {
 +
    int n = 3;
 +
    while (n) {
 +
        sleep(1);
 +
       
 +
        if (rand() < (RAND_MAX / (activities_ + 1)))
 +
            create_an_activity();
 +
 
 +
        if (rand() < (RAND_MAX / (daemons_ + 1)))
 +
            create_a_daemon();
 +
 
 +
        -- n;
 +
    }
 +
 
 +
    end_of_activity();
 +
}
 +
 
 +
static void create_an_activity(void) {
 
     pthread_attr_t attr;
 
     pthread_attr_t attr;
 
      
 
      
Line 25: Line 168:
 
      
 
      
 
     pthread_t bt;
 
     pthread_t bt;
     pthread_create(&bt, &attr, holder, NULL);
+
     pthread_create(&bt, &attr, activity, NULL);
 
     pthread_attr_destroy(&attr);
 
     pthread_attr_destroy(&attr);
 +
   
 +
    new_activity();
 
}
 
}
  
  
static void * holded(void * gr) {
+
static void * print_daemon(void * gr) {
     fprintf(stderr, "%s - tid: %x\n", __PRETTY_FUNCTION__, pthread_self());
+
     while (1) {
 +
        fprintf(stderr, "activities: %u  daemons: %u\n", activities_, daemons_);
  
    sleep(10);
+
        sleep(1);
 +
    }
  
 
     pthread_exit(NULL);
 
     pthread_exit(NULL);
 
}
 
}
  
static pthread_t hd;
 
  
static void join_holded(void) {
+
static pthread_t print_daemon_hd;
 +
 
 +
static void join_print_daemon(void) {
 
     fprintf(stderr, "%s - tid: %x\n", __PRETTY_FUNCTION__, pthread_self());
 
     fprintf(stderr, "%s - tid: %x\n", __PRETTY_FUNCTION__, pthread_self());
  
 
     // You may want to cancel a thread actively during termination:
 
     // You may want to cancel a thread actively during termination:
     pthread_cancel(hd);
+
     pthread_cancel(print_daemon_hd);
 
     // respectively
 
     // respectively
 
     //pthread_kill();
 
     //pthread_kill();
  
     pthread_join(hd, NULL);
+
    fprintf(stderr, "%s - joining print daemon ...\n", __PRETTY_FUNCTION__);
 +
     pthread_join(print_daemon_hd, NULL);
 
}
 
}
  
static void createHoldedThread(void) {
+
static void create_print_daemon(void) {
     pthread_create(&hd, NULL, holded, NULL);
+
     pthread_create(&print_daemon_hd, NULL, print_daemon, NULL);
     atexit(join_holded);
+
     atexit(join_print_daemon);
 
}
 
}
  
  
 
static void print_something(void) {
 
static void print_something(void) {
     fprintf(stderr, "%s - printing ... tid: %x\n", __PRETTY_FUNCTION__, pthread_self());
+
     fprintf(stderr, "activities: %u  daemons: %u\n", activities_, daemons_);
 
}
 
}
  
 
int main(void) {
 
int main(void) {
 +
    srand (time (0));
 +
 
     atexit(print_something);
 
     atexit(print_something);
 +
    atexit(join_daemons);
  
     createHolderThread();
+
     create_print_daemon();
 +
    create_a_daemon();
 +
    create_an_activity();
  
     createHoldedThread();
+
     sleep(3);
 +
    create_a_daemon();
  
     pthread_exit(NULL);
+
     sleep(5);
 +
    end_of_activity();
  
 
     return 0;
 
     return 0;
 
}
 
}
 
</code>
 
</code>

Revision as of 13:25, 4 September 2007

[cpp] // // gcc -g main.c -o main.bin -lpthread //

  1. include <stdlib.h>
  2. include <stdio.h>
  3. include <pthread.h>
  4. include <string.h>


typedef struct Daemon Daemon;

struct Daemon {

   Daemon * previous_;
   Daemon * next_;
   pthread_t hd_;

};

static Daemon * firstDaemon_ = NULL; static unsigned int daemons_ = 0; static pthread_mutex_t daemons_mutex_ = PTHREAD_MUTEX_INITIALIZER;

static Daemon * new_daemon(void) {

   Daemon * daemon = malloc(sizeof(Daemon));
   
   pthread_mutex_lock(&daemons_mutex_);
   daemon->previous_ = NULL;
   daemon->next_ = firstDaemon_;
   if (firstDaemon_) 
       firstDaemon_->previous_ = daemon;
   firstDaemon_ = daemon;
   ++ daemons_;
   pthread_mutex_unlock(&daemons_mutex_);
   return daemon;

}

static void end_of_daemon(void * context) {

   Daemon * daemon = (Daemon *)context;
   pthread_mutex_lock(&daemons_mutex_);
   -- daemons_;
   if (daemon->next_)
       daemon->next_->previous_ = daemon->previous_;
   if (daemon->previous_)
       daemon->previous_->next_ = daemon->next_;
   if (firstDaemon_ == daemon)
       firstDaemon_ = daemon->next_;
   pthread_mutex_unlock(&daemons_mutex_);
   free(daemon);
   // This thread is not in the list of daemons anymore, 
   // and therefor can't be joined.
   pthread_detach(pthread_self());

}

static void create_a_daemon(void);

static void * daemon_func(void * para) {

   pthread_cleanup_push (end_of_daemon, para);
   int n = 10;
   while (n) {
       sleep(1);
       
       if (rand() < (RAND_MAX / (daemons_ + 1)))
           create_a_daemon();
       -- n;
   }
   pthread_cleanup_pop(1);
   return NULL;

}

static void join_daemons(void) {

   fprintf(stderr, "%s ... ", __PRETTY_FUNCTION__, pthread_self());
   pthread_mutex_lock(&daemons_mutex_);
   while (firstDaemon_) {
       pthread_t hd;
       memcpy(&hd, &firstDaemon_->hd_, sizeof(pthread_t));
       pthread_mutex_unlock(&daemons_mutex_);
       // We may want to cancel a thread actively during termination:
       pthread_cancel(hd);
       // respectively
       //pthread_kill();
       pthread_join(hd, NULL);
       pthread_mutex_lock(&daemons_mutex_);
   }
   pthread_mutex_unlock(&daemons_mutex_);
   fprintf(stderr, "done\n");

}

static void create_a_daemon(void) {

   Daemon * daemon = new_daemon();
   pthread_create(&daemon->hd_, NULL, daemon_func, daemon);

}


static unsigned int activities_ = 1; // The "main" thread is the first "activity". static pthread_mutex_t activity_mutex_ = PTHREAD_MUTEX_INITIALIZER;

static void new_activity(void) {

   pthread_mutex_lock(&activity_mutex_);
   ++ activities_;
   pthread_mutex_unlock(&activity_mutex_);

}

static void end_of_activity(void) {

   int use_exit = 0;
   pthread_mutex_lock(&activity_mutex_);
   -- activities_;
   use_exit = activities_ == 0;
   pthread_mutex_unlock(&activity_mutex_);
  // Terminate the process, if this was the last "activity"!
   if (use_exit) 
       exit(0);
   else
       pthread_exit(NULL);

}

static void create_an_activity(void);

static void * activity(void * gr) {

   int n = 3;
   while (n) {
       sleep(1);
       
       if (rand() < (RAND_MAX / (activities_ + 1)))
           create_an_activity();
       if (rand() < (RAND_MAX / (daemons_ + 1)))
           create_a_daemon();
       -- n;
   }
   end_of_activity();

}

static void create_an_activity(void) {

   pthread_attr_t attr;
   
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, 1);
   
   pthread_t bt;
   pthread_create(&bt, &attr, activity, NULL);
   pthread_attr_destroy(&attr);
   
   new_activity();

}


static void * print_daemon(void * gr) {

   while (1) {
       fprintf(stderr, "activities: %u  daemons: %u\n", activities_, daemons_);
       sleep(1);
   }
   pthread_exit(NULL);

}


static pthread_t print_daemon_hd;

static void join_print_daemon(void) {

   fprintf(stderr, "%s - tid: %x\n", __PRETTY_FUNCTION__, pthread_self());
   // You may want to cancel a thread actively during termination:
   pthread_cancel(print_daemon_hd);
   // respectively
   //pthread_kill();
   fprintf(stderr, "%s - joining print daemon ...\n", __PRETTY_FUNCTION__);
   pthread_join(print_daemon_hd, NULL);

}

static void create_print_daemon(void) {

   pthread_create(&print_daemon_hd, NULL, print_daemon, NULL);
   atexit(join_print_daemon);

}


static void print_something(void) {

   fprintf(stderr, "activities: %u  daemons: %u\n", activities_, daemons_);

}

int main(void) {

   srand (time (0));
   atexit(print_something);
   atexit(join_daemons);
   create_print_daemon();
   create_a_daemon();
   create_an_activity();
   sleep(3);
   create_a_daemon();
   sleep(5);
   end_of_activity();
   return 0;

}

Personal tools