APUE Threads

  • A thread ID is represented by the pthread_t data type. Implementations are allowed to use a structure to represent the pthread_t data type

    1
    2
    3
    #include <pthread.h>
    int pthread_equal(pthread_t tid1, pthread_t tid2);
    Returns: nonzero if equal, 0 otherwise
  • A thread can obtain its own thread ID by calling the pthread_self function.

    1
    2
    pthread_t pthread_self(void);
    Returns: the thread ID of the calling thread
  • Thread Creation

    1
    2
    3
    4
    int pthread_create(pthread_t *restrict tidp,
    const pthread_attr_t *restrict attr,
    void *(*start_rtn)(void *), void *restrict arg);
    Returns: 0 if OK, error number on failure

Note that the pthread functions usually return an error code when they fail. They don’t set errno like the other POSIX functions.

  • Thread Termination
    A single thread can exit in three ways, thereby stopping its flow of control, without terminating the entire process.
  1. return from the start routine. The return value is the thread’s exit code.
  2. be canceled by another thread in the same process.
  3. pthread_exit.
    1
    2
    3
    void pthread_exit(void *rval_ptr);
    int pthread_join(pthread_t thread, void **rval_ptr);
    Returns: 0 if OK, error number on failure
  • pthread_cancel: One thread cancel another in the same process

    pthread_cancel doesn’t wait for the thread to terminate; it merely makes the request.

    1
    2
    3
    int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,
    const struct timespec *restrict tsptr);
    Returns: 0 if OK, error number on failure

the timeout value is reached, pthread_mutex_timedlock will return the error code ETIMEDOUT without locking the mutex.

  • Reader–Writer Locks
    hare in read, exclusive in write
    1
    2
    3
    4
    5
    6
    7
    int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
    const pthread_rwlockattr_t *restrict attr);
    int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
    int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
    All return: 0 if OK, error number on failure
  • Cond_wait

    1
    2
    3
    4
    #include <pthread.h>
    int pthread_cond_signal(pthread_cond_t *cond);
    int pthread_cond_broadcast(pthread_cond_t *cond);
    Both return: 0 if OK, error number on failure
  • Cancel

    1
    2
    3
    4
    5
    6
    #include <pthread.h>
    int pthread_setcancelstate(int state, int *oldstate);
    $ state : PTHREAD_CANCEL_ENABLE/ PTHREAD_CANCEL_DISABLE
    int pthread_setcanceltype(int type, int *oldtype);
    # type : PTHREADCANCEL_DEFERRED / PTHREADCANCEL_ASYNCHRONOUS
    Returns: 0 if OK, error number on failure
  • Signal

    1
    2
    3
    4
    5
    #include <semaphore.h>
    int sem_init(sem_t *sem, 0, unsigned int value);
    int sem_wait(sem_t *s)//P
    int sem_post(sem_t *s)//V
    success return 0, else -1
  • 线程安全

    不安全函数类

    1. 不保护共享变量
    2. 保持跨越多个调用状态的函数 :非原子操作
    3. 返回指向静态变量指针的函数 :某个线程的返回覆盖其他线程的调用
    4. 调用线程部不安全函数
      • 调用2类线程一定不安全,只能重写保证线程安全
      • 调用1,3类时,用互斥所保护共享变量则线程安全
    • reentrant funtion : never change any shared-variables.
    • reentrant funtion is a subset of thread-safe funtion
    • some thread-safe funtion may be not reentrant.

    none-thread-safe library funtions

    • rand
    • strtok
    • asctime
    • ctime
    • gethostbyaddr/gethostbyname
    • int_ntoa
    • locatime

    互斥锁加锁,同时占用s,t两个锁的线程必须以相同顺序给s,t加锁