Posix Threads API 整理
定义: 并发与并行: 并发(concurrency):实际上串行发生的事情好像同时发生,表述了单核处理器中线程或者进程的行为特点 并行(parallelism):并发序列同时执行, 真正的并行只能在多处理其上存在。 异步与同步: 异步(asynchronous)与同步(synchronous)区别在于发需求的人是否需要等到需要完成才可以执行其他事情。 线程安全和可重入: 线程安全:能够被多个线程调用而不会产生灾难性结果,大部分函数可以利用互斥量,条件变量,线程私有数据实现线程安全。 可重入:采用比将函数和库转换为一系列更为复杂方式使得代码成为线程安全。可重入函数应该避免任何静态数据和共享全局数据,避免依赖线程间任何形式的同步。 数据类型: 线程相关数据类型 类型 描述 pthread_t 线程标识符 pthread_mutex_t 互斥量 pthread_spinlock_t 自旋锁 pthread_cond_t 条件变量 pthread_key_t 线程私有数据访问键 pthread_attr_t 线程属性对象 pthread_mutexattr_t 互斥量属性对象 pthread_rwlockattr_t 读写锁属性 pthread_condattr_t 条件变量属性对象 pthread_once_t 一次性初始化属性对象 sigevent 线程通知机制 线程POSIX API: 基本操作 建立与终止 pthread_create pthread_exit 等待 pthread_join 取消 pthread_cancel 线程分离 pthread_detach 获取线程标识符 pthread_self 比较线程标识符 pthread_equal 基本操作 example 建立与终止 pthread_create pthread_exit 等待 pthread_join //线程创建 #include <pthread.h> #include <stdlib.h> #include <stdio.h> void * thread (void *arg) { char *ret; printf ("thread() entered with argument '%s'\n", arg); if ((ret = (char *) malloc (20)) == NULL) { perror ("malloc() error"); exit (2); } strcpy (ret, "This is a test"); pthread_exit (ret); } main () { pthread_t thid; void *ret; if (pthread_create (&thid, NULL, thread, "thread 1") != 0) { perror ("pthread_create() error"); exit (1); } if (pthread_join (thid, &ret) != 0) { perror ("pthread_create() error"); exit (3); } printf ("thread exited with '%s'\n", ret); } [root@centosgpt threaddemo]# ./create thread() entered with argument 'thread 1' thread exited with 'This is a test'. 取消 pthread_cancel //线程取消, 通过pthread_cancel 取消正在运行的线程 #include <errno.h> #include <pthread.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> int thstatus; void * thread (void *arg) { puts ("thread has started. now sleeping"); while (1) sleep (1); } main (int argc, char *argv[]) { pthread_t thid; void *status; if (pthread_create (&thid, NULL, thread, NULL) != 0) { perror ("pthread_create failed"); exit (2); } if (pthread_cancel (thid) == -1) { perror ("pthread_cancel failed"); exit (3); } if (pthread_join (thid, &status) == -1) { perror ("pthread_join failed"); exit (4); } if (status == (int *) -1) puts ("thread was cancelled"); else puts ("thread was not cancelled"); exit (0); } [root@centosgpt threaddemo]# ./cancel thread has started. now sleeping thread was cancelled 线程分离 pthread_detach // 线程分离, 线程退出后自动释放资源 #include <stdlib.h> #include <stdio.h> void * thread (void *arg) { char *ret; printf ("thread() entered with argument '%s'\n", arg); if ((ret = (char *) malloc (20)) == NULL) { perror ("malloc() error"); exit (2); } strcpy (ret, "This is a test"); pthread_exit (ret); } main () { pthread_t thid; void *ret; if (pthread_create (&thid, NULL, thread, "thread 1") != 0) { perror ("pthread_create() error"); exit (1); } if (pthread_detach (&thid) != 0) { perror ("pthread_detach() error"); exit (4); } sleep(2); printf ("thread exited with '%s'\n", ret); } [root@centosgpt threaddemo]# ./detach thread() entered with argument 'thread 1' thread exited with '(null)' [root@centosgpt threaddemo]# ./detach pthread_detach() error: Success 获取线程标识符 pthread_self 比较线程标识符 pthread_equal #include <pthread.h> #include <stdio.h> pthread_t thid, IPT; void * thread (void *arg) { if (pthread_equal (IPT, thid)) puts ("the thread is the IPT...?"); else puts ("the thread is not the IPT"); } main () { IPT = pthread_self (); if (pthread_create (&thid, NULL, thread, NULL) != 0) { perror ("pthread_create() error"); exit (1); } if (pthread_join (thid, NULL) != 0) { perror ("pthread_create() error"); exit (3); } } [root@centosgpt threaddemo]# ./self the thread is not the IPT [root@centosgpt threaddemo]# 私有数据 私有数据创建 pthread_key_create pthread_key_delete 私有数据使用 pthread_setspecific pthread_getspecific 私有数据 example 私有数据创建 pthread_key_create pthread_key_delete 私有数据使用 pthread_setspecific pthread_getspecific #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <pthread.h> #define threads 3 #define BUFFSZ 48 pthread_key_t key; void * threadfunc (void *parm) { int status; void *value; int threadnum; int *tnum; void *getvalue; char Buffer[BUFFSZ]; tnum = parm; threadnum = *tnum; printf ("Thread %d executing\n", threadnum); if (!(value = malloc (sizeof (Buffer)))) printf ("Thread %d could not allocate storage, errno = %d\n", threadnum, errno); sprintf (value, "Thread %d executing\n", threadnum); status = pthread_setspecific (key, (void *) value); if (status < 0) { printf ("pthread_setspecific failed, thread %d, errno %d", threadnum, errno); pthread_exit ((void *) 12); } printf ("Thread %d setspecific value: %d\n", threadnum, value); getvalue = 0; getvalue = pthread_getspecific (key); if (status < 0) { printf ("pthread_getspecific failed, thread %d, errno %d", threadnum, errno); pthread_exit ((void *) 13); } printf("key = %s\n", getvalue); if (getvalue != value) { printf ("getvalue not valid, getvalue=%d", (int) getvalue); pthread_exit ((void *) 68); } pthread_exit ((void *) 0); } void destr_fn (void *parm) { printf ("Destructor function invoked\n"); free (parm); } main () { int getvalue; int status; int i; int threadparm[threads]; pthread_t threadid[threads]; int thread_stat[threads]; if ((status = pthread_key_create (&key, destr_fn)) < 0) { printf ("pthread_key_create failed, errno=%d", errno); exit (1); } for (i = 0; i < threads; i++) { threadparm[i] = i + 1; status = pthread_create (&threadid[i], NULL, threadfunc, (void *) &threadparm[i]); if (status < 0) { printf ("pthread_create failed, errno=%d", errno); exit (2); } } for (i = 0; i < threads; i++) { status = pthread_join (threadid[i], (void *) &thread_stat[i]); if (status < 0) { printf ("pthread_join failed, thread %d, errno=%d\n", i + 1, errno); } if (thread_stat[i] != 0) { printf ("bad thread status, thread %d, status=%d\n", i + 1, thread_stat[i]); } } exit (0); } [root@centosgpt threaddemo]# ./key Thread 1 executing Thread 2 executing Thread 1 setspecific value: -1140848448 key = Thread 1 executing Thread 2 setspecific value: -1275066176 key = Thread 2 executing Thread 3 executing Thread 3 setspecific value: -1207957312 key = Thread 3 executing Destructor function invoked Destructor function invoked Destructor function invoked 同步: 互斥量 互斥量创建与销毁 pthread_mutex_init pthread_mutex_destroy 加锁解锁互斥量(阻塞) pthread_mutex_lock pthread_mutex_unlock 加锁解锁互斥量(非阻塞) pthread_mutex_trylock 互斥变量优先级上限 pthread_mutex_getprioceiling pthread_mutex_setprioceiling 互斥量 example 互斥量创建与销毁: pthread_mutex_init pthread_mutex_destroy 加锁解锁互斥量(阻塞) pthread_mutex_lock pthread_mutex_unlock ## 阻塞模式 pthread_mutex_lock #include <pthread.h> #include <stdio.h> #include <errno.h> #include <stdlib.h> pthread_mutex_t mutex; void * thread (void *arg) { if (pthread_mutex_lock (&mutex) != 0) { perror ("pthread_mutex_lock() error"); exit (1); } puts ("thread was granted the mutex"); if (pthread_mutex_unlock(&mutex) != 0) { perror("pthread_mutex_unlock() error"); exit(2); } } main () { pthread_t thid; if (pthread_mutex_init (&mutex, NULL) != 0) { perror ("pthread_mutex_init() error"); exit (2); } if (pthread_create (&thid, NULL, thread, NULL) != 0) { perror ("pthread_create() error"); exit (3); } if (pthread_mutex_lock (&mutex) != 0){ perror ("pthread_mutex_lock() error"); exit (4); } puts ("IPT was granted the mutex"); if (pthread_mutex_unlock(&mutex) != 0) { perror("pthread_mutex_unlock() error"); exit(2); } if (pthread_join (thid, NULL) != 0) { perror ("pthread_mutex_trylock() error"); exit (5); } if (pthread_mutex_destroy(&mutex) != 0) { perror("pthread_mutex_destroy() error"); exit(2); } } [root@centosgpt threaddemo]# ./mutexb IPT was granted the mutex thread was granted the mutex 加锁解锁互斥量(非阻塞) pthread_mutex_trylock ### 非阻塞模式 #include <pthread.h> #include <stdio.h> #include <errno.h> #include <stdlib.h> pthread_mutex_t mutex; void * thread (void *arg) { int rc; while (1){ if ((rc=pthread_mutex_trylock (&mutex))!=0){ if (rc == EBUSY){ puts ("thread was denied access to the mutex"); continue; } else { perror ("sub pthread_mutex_trylock() error"); exit (1); } puts ("sub thread can do other thing"); } else { puts ("thread was granted the mutex"); break; } } if (pthread_mutex_unlock(&mutex) != 0) { perror("pthread_mutex_unlock() error"); exit(2); } } main () { pthread_t thid; int rc; if (pthread_mutex_init (&mutex, NULL) != 0) { perror ("pthread_mutex_init() error"); exit (2); } if (pthread_create (&thid, NULL, thread, NULL) != 0) { perror ("pthread_create() error"); exit (3); } while(1){ if ((rc=pthread_mutex_trylock (&mutex)) != 0){ if (rc == EBUSY){ puts ("IPT was denied access to the mutex"); continue; } else { perror ("main pthread_mutex_trylock() error"); exit (4); } puts ("main thread can do other thing"); } else { puts ("IPT was granted the mutex"); break; } } if (pthread_mutex_unlock(&mutex) != 0) { perror("pthread_mutex_unlock() error"); exit(2); } if (pthread_join (thid, NULL) != 0) { perror ("pthread_mutex_trylock() error"); exit (5); } if (pthread_mutex_destroy(&mutex) != 0) { perror("pthread_mutex_destroy() error"); exit(2); } } [root@centosgpt threaddemo]# ./mutex IPT was granted the mutex thread was denied access to the mutex thread was granted the mutex 互斥变量优先级上限 pthread_mutex_getprioceiling pthread_mutex_setprioceiling 依赖于互斥锁属性的协议的设置 ...