Category Archives: thread & process

Thread creation/termination

Thread Creation

int pthread_create(&tid, &attr, func, &arg);
Thread destroy
  1. in a different thread
    • int pthread_cancel( tid );  // tid can be pthread_self()
      • the cancellation type and state of the target thread determine when the cancellation takes effect.
    • int pthread_join(tid, **value_ptr);
    • int pthread_abort(tid);  // tid can be pthread_self()
      • termination takes effect immediately (don’t wait for a cancellation point).
      • no cancellation handler called.
      • resources are not released (mutexes, file descriptors, etc)
  2. in the thread itself
    • void pthread_exit(*value_ptr);
      • value_ptr: thread’s exit status, which carries whatever you want the other thread (e.g. the thread calls pthread_join()) to know.
      • when the thread start routine returns, pthread_exit() is called implicitly.
    • void pthread_cleanup_push(cleanup_handler, &arg)
    • void pthread_cleanup_pop(execute)  // execute = 0, means the handler will not be executed.
      • the cleanup handler is pop/executed when the thread:
        • exits
        • acts on a cancellation request.
        • calls pthread_cleanup_pop() with nonzero.
      • NOTE! the cleanup handler should support multiple entrances.
#include <pthread.h>
struct my_context;
void *my_thread1(void *arg)
{
    struct my_context *cx=(struct my_context *)arg;
    ….
    return NULL; // pthread_exit() is called implicitly
}
void my_cleanup(void *args)
{
    struct my_context *ctx = (struct my_context *)args;
    if(ctx->iid != -1) {
        InterruptDetach(ctx->iid);
    }
}
void *my_thread2(void *arg)
{
    struct my_context *cx=(struct my_context *)arg;
    ctx->iid = InterruptAttachEvent(…);
    pthread_cleanup_push(my_cleanup, ctx);
    ….
    pthread_cleanup_pop(1);
    return NULL;
}
int main(int argc, char **argv)
{
    struct my_context *ctx;
    // create a thread with default attributes.  Don’t care about thread ID.
    // pthread_create(NULL, NULL, my_thread1, ctx);
    // create a thread with priority set to +20
    pthread_t tid;
    pthread_attr_t attr;
    struct sched_param param;
    int allowable_prio;
    pthread_attr_init(&attr);
    pthread_getschedparam(pthread_self(), NULL, &param);
    allowable_prio = sched_get_priority_adjust(-1, SCHED_NOCHANGE, +20);
    param.sched_priority = allowable_prio;
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    // pthread_attr_setschedpolicy(&attr, policy);  is this required?
    pthread_attr_setschedparam(&attr, &param);
    pthread_create(&tid, &attr, my_thread1, ctx); // all pointers
pthread_join(tid, NULL);  // wait/block until the target thread(tid) has terminated.
}
Advertisements

Thread atributes

 Process and thread: processes own resources, threads run code.
(Default) thread attributes
  • PTHREAD_CREATE_JOINABLE: the thread is put into a zoombie state when it terminates, until you retrieve its exit status or detach it.
  • inherit-scheduling attribute
    • PTHREAD_INHERIT_SCHED: the thread inherits the scheduling policy of its parent thread.
    • another value: PTHREAD_EXPLICIT_SCHED
      • if we want to use different scheduling parameters for the new thread, this need to be changed to PTHREAD_EXPLICIT_SCHED.
  • cancellation state
    • PTHREAD_CANCEL_ENABLE: cancellation requests may be acted on accordingly to the cancelation type
    • another state: PTHREAD_CANCEL_DISABLE
  • cancellation type
    • PTHREAD_CANCEL_DEFERRED: cancellation requests are held pending until a cancellation point.
    • PTHREAD_CANCEL_A
  • 4K stack

Thread scheduling

  1. Scheduling policy: inherited from the parent process (PTHREAD_INHERT_SCHED), by default. In all cases, a higher-priority thread can preempts all lower-priority threads one it gets READY.
    • FIFO scheduling: apply only when two or more threads that share the same priority are READY.
    • Round-robin scheduling: a thread stop executing when it consumes its timeslice.
    • Sporadic scheduling
  2. Scheduling priority, independent of the scheduling policy. The scheduler selects the highest priority thread to run, from the READY threads.
    • range 0 ~ 255
      • 0 is for the special idle thread (in kernel), which is always ready to run.
      • 1 ~ 63 for user threads. (the range can be changed by pronto -P option).
      • 1 ~255 for root threads.

Data structure

  • pthread_attr_t: stack size, detachstate, schedparam, schedpolicy, etc
  • struct sched_param: contains sched_priority, sched_curpriority
  • int policy: FIFO(1), RR(2, default?), OTHER(3), SPORADIC(4)

 APIs

  1. process level
    • Get/set the priority of a process; if pid 0 used, it is for current process.
      • sched_setparam(pid|0, &sched_param): 
      • sched_getparam(pid|0, &sched_param);
    • get the priority range for the scheduling policy
      • sched_get_priority_max(int policy);
      • sched_get_priority_min(int policy);
    • calculate the allowable priority for the policy
      • allowable_priority = sched_get_priority_adjust(int priority, int policy, int adjust);
        • priority = -1, priority of current thread.
        • policy=SCHED_NOCHANGE, the policy of the called thread
        • adjust=+20, we want a priority of “priority + 20”.
  2. thread level (used after the thread is created)
    • Set/get scheduling parameters
      • pthread_getschedparam(tid, &policy, &param);
      • pthread_setschedparam(tid, policy, &param)
    • set the priority
      • pthread_setschedprio(tid, prio);
      • Note: the priority get should be achieved using pthread_getschedparam().
    • set cancellation state/type
      • pthread_setcancelstate(int newstate, &oldstate)
      • pthread_setcanceltype(int newtype, &oldtype);
        • not _get functions.
        • can only be set after thread creation.
  3. attribute level (only take effect before the thread is created)
    • initialize/destroy attr object
      • pthread_attr_init(&attr)
      • pthread_attr_destroy(&attr);  // the memory is not freed. but after destroying, reinit the object using pthread_attr_init()
    • set/get policy
      • pthread_attr_setschedpolicy(&attr, int policy)
      • pthread_attr_getschedpolicy(&attr, &policy)
    • set/get scheduling parameters
      • pthread_attr_setschedparam(&attr, &param);
        • used only after pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
      • pthread_attr_getschedparam(&attr, &param);
    • set/get inherit-scheduling attributes
      • pthread_attr_setinheritsched(&attr, interitsched);
      • pthread_attr_getinheritsched(&attr, &interitsched);
        • need to be set prior to the thread creation