20091216

English - Class Notes 04

Numbers

Temperature
  • 1 °C: one degree Celsius
  • 1 °F: one degree Fahrenheit

Time, for example 08:00
  • 8 o'clock on the dot
  • 8 o'clock sharp

Fraction/Ratio
  • 1/4: one over four
  • 1/3: one third
  • 2/3: two thirds
  • 4:1: four to one


Currency
  • 123,456: one hundred twenty-three thousand four hundred and fifty-six
  • 1,234.56: one thousand and two hundred thirty-four point five six
  • 1,000: one grand

Space
  • 1 m2: one square metre

20091204

Java - Some Fundamental Concepts

Method declaration in an interface,
  • Correct:
    abstract void doStuff();
    protected abstract void doStuff();
    
  • Incorrect:
    public abstract static void doStuff();
    private abstract void doStuff();
    final abstract void doStuff();
    

Overloading & Overriding,
  • Cans:
    • Instance method can be overloaded.
    • Instance method can be overriden.
    • Static method can be overloaded.
    • Constructor can be overloaded.
  • Cants:
    • Static method can't be overriden.
    • Constructor can't be overriden.
    • Instance field can't be overloaded.
    • Instance field can't be overriden.

A constructor may only access final or static attributes, therefore following is incorrect.
class Base { 
     private int value; 
      
     Base (int v) { 
         value = v; 
     } 
  
     public int getValue() { 
         return value; 
     } 
 } 
  
 public class Derived extends Base { 
     int currentValue = 1; 
  
     public Derived() { 
         super(currentValue); 
         currentValue++; 
     } 
 }

An assert statement can take any one of following two forms, method call isn't allowed:
assert Expression1; 
assert Expression1 : Expression2; 

Inheritance and abstract modifier, following are correct
  • Method could be declared as abstract in a child.
  • Class could be declared as abstract even if it doesn't have any abstract method.
  • Static method can be overloaded.

Implementation of an interface, following code snippet isn't correct because all interface methods are default public methods.
interface Useable { 
   void doIt(); 
} 
  
public class Test implements Useable {    
   public Test(){} 
   void doIt() {} 
}

Notification in threads
  • If a thread issues a notifyAll on an object without having acquired the lock for the object Java throws an IllegalMonitorStateException.

Appropriate uses for Assertion statements
  • Should be used to validate private method parameters.
  • Should be used to check for cases that should never occur.

Interface and abstract constructors
  • Abstract classes have constructors, and those constructors are always called when a concrete subclass is instantiated using the new operator.

Java - Classes Comparison

Hashtable v.s. HashMap
  • Hashtable: Synchronized
  • HashMap: Non synchronized

StringBuffer v.s. StringBuilder
  • StringBuffer: Synchronized
  • StringBuilder: Non synchronized

List v.s. Set
  • List: Allow duplicate elements
  • Set: Not allow duplicate elements

20091116

C - pthread_cond_timedwait_relative_np example

Follow up of previous post, try to simulate the sigtimedwait method due to the fact that the method is lacked in OS X.

BTW, ldd is also not found, just use otool -L for an alternative.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>

#define SIG_A          (SIGUSR2 - 0)
#define SIG_B          (SIGUSR2 - 1)
#define SIG_C          (SIGQUIT)

#define S  1
#define F  0

#define TIMES 10

/*
 * data structure
 */
typedef struct _proc {
    char            name[2];
    int             data;
    pthread_t       thread;
    pthread_mutex_t lock;
    pthread_cond_t  cond;
    long int        waits;
    sigset_t        sigset;
} PROC;

/*
 * variables
 */

static PROC *listener;

/*
 * methods
 */
void _exec_and_wait(void* args) {
    PROC *proc = (PROC*) args;
    static struct timespec time_to_wait = {0, 0};
    // signal version
    int recSignal;
    while(proc->data < 999) {
        if (0 == sigwait(&proc->sigset, &recSignal)) {
            pthread_mutex_lock(&proc->lock);
            switch (recSignal) {
                case SIG_A:
                    printf("proc[%s] receive SIG_A\n", proc->name);
                    proc->data++;
                break;
                case SIG_B:
                    printf("proc[%s] receive SIG_B\n", proc->name);
                    proc->data += 5;
                break;
                case SIG_C:
                    printf("proc[%s] receive SIG_C\n", proc->name);
                    proc->data += 999;
                break;
                default:
                    printf("proc[%s] receive unknow signal [%d]\n", proc->name, recSignal);
            }
            pthread_mutex_unlock(&proc->lock);
        } else {
            printf("proc[%s] fail to receive signal [%d]\n", proc->name);
        }
    }
    printf("proc[%s] finished\n", proc->name);
}

void _exec_to_signal(void* args) {
    PROC *proc = (PROC*) args;
    static struct timespec time_to_wait = {0, 0};
    int sig_sending;
 
    if (listener != NULL) {
        srand(time(NULL));
        time_to_wait.tv_sec = proc->waits;
        while(proc->data < TIMES) {
            pthread_mutex_lock(&proc->lock);
            pthread_cond_timedwait_relative_np(&proc->cond, &proc->lock, &time_to_wait);
            sig_sending = (rand() % 2 > 0) ? SIG_A : SIG_B;
            printf("proc[%s] is sending signal[%d]\n", proc->name, sig_sending);
            pthread_kill(listener->thread, sig_sending);
            proc->data++;
            pthread_mutex_unlock(&proc->lock);
        }
        printf("proc[%s] is sending signal[%d]\n", proc->name, SIG_C);
        pthread_kill(listener->thread, SIG_C); // to terminate listener
    } else {
        printf("proc[%s] is aborting signal[%d], due to no listener registered\n", proc->name, SIG_A);
 }
 printf("proc[%s] finished\n", proc->name);
}

int _init_proc(PROC *proc, void *(*routine) (void *)) {
    pthread_attr_t attr;
    //
    printf("try to init proc [%s]\n", proc->name);
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    //
    pthread_mutex_init(&proc->lock, NULL);
    pthread_cond_init(&proc->cond, NULL);
    //
    pthread_create(&proc->thread, &attr, routine, (void*) proc);
    pthread_attr_destroy(&attr);
    //
    return S;
}

int _init_signal_proc(PROC *proc, void *(*routine) (void *)) {
    pthread_attr_t attr;
    //
    printf("try to init proc [%s]\n", proc->name);
    //
    sigemptyset(&proc->sigset);
    sigaddset(&proc->sigset, SIG_A);
    sigaddset(&proc->sigset, SIG_B);
    sigaddset(&proc->sigset, SIG_C);
    pthread_sigmask(SIG_BLOCK, &(proc->sigset), NULL);
    //
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    //
    pthread_mutex_init(&proc->lock, NULL);
    //
    pthread_create(&proc->thread, &attr, routine, (void*) proc);
    pthread_attr_destroy(&attr);
    //
    return S;
}

/*
 *  main
 */
int main(int argc, char** argv)
{
    int  result_a = 0, result_b = 0;
    PROC proc_a, proc_b;

    strcpy(proc_a.name, "A\0");
    proc_a.data = 0;
    proc_a.waits = 1L;

    strcpy(proc_b.name, "B\0");
    proc_b.data = 0;
    proc_b.waits = 800L;

    listener = &proc_b;

    if (!_init_proc(&proc_a, _exec_to_signal))
        printf("Fail to init proc [%s]\n", proc_a.name);
    /* */
    if (!_init_signal_proc(&proc_b, _exec_and_wait))
        printf("Fail to init proc [%s]\n", proc_b.name);
 
    /* */
    pthread_join(proc_a.thread, (void*) &result_a);
    pthread_join(proc_b.thread, (void*) &result_b);

    return (EXIT_SUCCESS);
}

20091113

C - pthread_cond_timedwait example

Follow up: try to use pthread_cond_timedwait_relative_np on OS X.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>

#define S  1
#define F  0

#define TIMES 10

/*
 * data structure
 */
typedef struct _proc {
    char            name[2];
    int             data;
    pthread_t       thread;
    pthread_mutex_t lock;
    pthread_cond_t  cond;
    long int        waits;
} PROC;

void _exec_and_wait(void* args) {
    static struct timespec time_to_wait = {0, 0};
    PROC *proc = (PROC*) args;

    while(proc->data < TIMES) {
        time_to_wait.tv_sec = time(NULL) + proc->waits;
        pthread_mutex_lock(&proc->lock);
        pthread_cond_timedwait(&proc->cond, &proc->lock, &time_to_wait);
        proc->data++;
        printf("increase proc[%s] data to [%d]\n", proc->name, proc->data);
        pthread_mutex_unlock(&proc->lock);
    }
}

int _init_proc(PROC *proc, void *(*routine) (void *)) {
    pthread_attr_t attr;
    //
    printf("try to init proc [%s]\n", proc->name);
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    //
    pthread_mutex_init(&proc->lock, NULL);
    pthread_cond_init(&proc->cond, NULL);
    //
    pthread_create(&proc->thread, &attr, routine, (void*) proc);
    pthread_attr_destroy(&attr);
    //
    return S;
}

/*
 *  main
 */
int main(int argc, char** argv)
{
    int  result_a = 0, result_b = 0;
    PROC proc_a, proc_b;

    strcpy(proc_a.name, "A\0");
    proc_a.data = 0;
    proc_a.waits = 2L;

    strcpy(proc_b.name, "B\0");
    proc_b.data = 0;
    proc_b.waits = 1L;

    if (!_init_proc(&proc_a, _exec_and_wait))
        printf("Fail to init proc [%s]\n", proc_a.name);
    /* */
    if (!_init_proc(&proc_b, _exec_and_wait))
        printf("Fail to init proc [%s]\n", proc_b.name);
    /* */
    pthread_join(proc_a.thread, (void*) &result_a);
    pthread_join(proc_b.thread, (void*) &result_b);

    return (EXIT_SUCCESS);
}