一.线程的必要性
1.某个非常耗时的操作,可由单独的线程完成
2.线程共享进程的地址空间,文件描述符等
3.线程私有数据包括:(1)线程号(2)寄存器(3)堆栈(4)信号掩码(5)优先级(6)线程私有的存储空间
二.创建进程
1.相关函数

Code
1 #include <pthread.h>
2 int pthread_create(pthread_t *thread,pthread_attr_t *attr,void *(*start_routine)(void *),void *arg);
3 pthread_t pthread_self(void);
4 int pthread_equal(pthread_t thread1,pthread_t thread2);
5 int pthread_once(pthread_once_t *once_control,void(*init_routine)(void));
2.线程属性

Code
1 /* man pthread_attr_init */
2 typedef struct
3 {
4 int detachstate; //是否与其他线程脱离同步
5 int schedpolicy; //新线程的调度策略
6 struct sched_param schedparam; //运行优先级等
7 int inheritsched; //是否继承调用者线程的值
8 int scope; //线程竞争CPU的范围(优先级的范围)
9 size_t guardsize; //警戒堆栈的大小
10 int stackaddr_set; //堆栈地址集
11 void * stackaddr; //堆栈地址
12 size_t stacksize; //堆栈大小
13 } pthread_attr_t;
14
15 /* 获取和设置函数 */
16 int pthread_getdetachstate(pthread_attr_t *attr,int *detachstate);
17 int pthread_attr_setinherisched(pthread_attr_t *attr,int *inherisched);
Code
pthread_once:

Code
1 #include <stdio.h>
2 #include <pthread.h>
3 #include <unistd.h>
4
5 pthread_once_t once=PTHREAD_ONCE_INIT;
6 //int once=0;
7 void run(void)
8 {
9 printf("Fuction run is running in thread %lu\n",pthread_self());
10 }
11
12 void *thread1(void *arg)
13 {
14 pthread_t thid=pthread_self();
15 printf("Current thread ID is %lu\n",thid);
16 pthread_once(&once,run);
17 printf("thread1 ends\n");
18 return NULL;
19 }
20
21 void *thread2(void *arg)
22 {
23 pthread_t thid=pthread_self();
24 printf("Current thread ID is %lu\n",thid);
25 pthread_once(&once,run);
26 printf("thread2 ends\n");
27 return NULL;
28 }
29
30 int main()
31 {
32 pthread_t thid1,thid2;
33 pthread_create(&thid1,NULL,(void*)thread1,NULL);
34 pthread_create(&thid2,NULL,(void*)thread2,NULL);
35 sleep(3);
36 printf("main thread exit!\n");
37 return 0;
38 }
三.终止线程
1.线程函数返回;main返回时所有线程结束;
2.pthread_exit();子线程仍继续,进程也末消亡;
终止线程相关:
(1).释放临界资源.pthread_cleanup_push(routine,arg)与pthread_cleanup_pop()中如调用返回,则执行
routine清理函数,这两个宏需成对出现;
(2).线程间同步.
1 #include <pthread.h>
2 void pthread_exit(void *retval);
3 void pthread_join(pthread_t th,void *thread_return); //挂起等待th结束,*thread_return=retval;
4 int pthread_detach(pthread_t th);
线程只能被一个线程等待终止(第一个能正常返回),并且应处于join状态(非DETACHED),因此避免内存泄漏,所
有线程应调用pthread_detach()(被设置为DETACHED)或被一个线程pthread_join(),例子:

Code
1 #include <stdio.h>
2 #include <pthread.h>
3 #include <unistd.h>
4
5 void assisthread(void *arg)
6 {
7 printf("I am helping to do some job\n");
8 sleep(3);
9 pthread_exit(0);
10 }
11 int main(void)
12 {
13 pthread_t assistthid;
14 int status;
15 pthread_create(&assistthid,NULL,(void*) assisthread,NULL);
16 printf("assistthread's exit is caused %d\n",status);
17 return 0;
18 }
19
四.私有数据
1.线程中的全局变量为所有线程共有,所以象erron这样的变量得通过TSD(Thread-specific Data)解决,采用一
键多值技术;为每个键指定一个键值.
2.操作线程数据的函数:

Code
1 #include <pthread.h>
2 int pthread_key_creadte(pthread_key_t *key,void (*destr_fuction) (void *));
3 int pthread_setspecific(pthread_key_t key,const void * pointer));
4 void * pthread_getspecific(pthread_key_t key);
5 int pthread_key_delete(ptherad_key_t key);
6
TSD程序如下:

Code
1 #include <stdio.h>
2 #include <pthread.h>
3 #include <unistd.h>
4 pthread_key_t key;
5 void *thread2(void *arg)
6 {
7 int tsd=1;
8 printf("thread %d is runnig\n",pthread_self());
9 pthread_setspecific(&key,(void*)tsd);
10 printf("thread %d returns %d\n",pthread_self(),pthread_getspecific(key));
11 printf("thread %d returns %d\n",pthread_self(),tsd);
12 return NULL;
13 }
14 void *thread1(void *arg)
15 {
16 int tsd=5;
17 pthread_t thid2;
18 printf("thread %d is runnig\n",pthread_self());
19 pthread_setspecific(&key,(void*)tsd);
20 pthread_create(&thid2,NULL,(void*)thread2,NULL);
21 sleep(3);
22 printf("thread %d returns %d\n",pthread_self(),pthread_getspecific(key));
23 return NULL;
24 }
25
26 int main()
27 {
28 pthread_t thid1;
29 printf("main thread begins running\n");
30 pthread_key_create(&key,NULL);//NULL退出线程时函数,以关联数据为参数
31 pthread_create(&thid1,NULL,(void*)thread1,NULL);
32 sleep(5);
33 pthread_key_delete(key);
34 printf("main thread exit!\n");
35 return 0;
36
五.线程同步
1.互斥锁

Code
1 int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);
2 int pthread_mutex_lock(pthread_mutex *mutex);
3 int pthread_mutex_destroy(pthread_mutex *mutex);
4 int pthread_mutex_unlock(pthread_mutex *
(1)先初始化锁init()或静态赋值pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIER
attr_t有:
PTHREAD_MUTEX_TIMED_NP:其余线程等待队列
PTHREAD_MUTEX_RECURSIVE_NP:嵌套锁,允许线程多次加锁,不同线程,解锁后重新竞争
PTHREAD_MUTEX_ERRORCHECK_NP:检错,与一同,线程请求已用锁,返回EDEADLK;
PTHREAD_MUTEX_ADAPTIVE_NP:适应锁,解锁后重新竞争
(2)加锁,lock,trylock,lock阻塞等待锁,trylock立即返回EBUSY
(3)解锁,unlock需满足是加锁状态,且由加锁线程解锁
(4)清除锁,destroy(此时锁必需unlock,否则返回EBUSY,//Linux下互斥锁不占用资源内存
2.条件变量(需用锁保护)通过线程共享的全局变量进行同步.等待使用资源的线程等待条件变量被
设置为真.另一个线程使用完资源后,设置条件变量为真

Code
1 int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);
2 int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
3 int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);
4 int pthread_cond_destroy(pthread_cond_t *cond);
5 int pthread_cond_signal(pthread_cond_t *cond);
6 int pthread_cond_broadcast(pthread_cond_t *cond); //解除所有线程的阻塞
(1)初始化.init()或者pthread_cond_t cond=PTHREAD_COND_INITIALIER;属性置为NULL
(2)等待条件成立.pthread_wait,pthread_timewait.wait()释放锁,并阻塞等待条件变量为真
timewait()设置等待时间,仍未signal,返回ETIMEOUT(加锁保证只有一个线程wait)
(3)激活条件变量:pthread_cond_signal,pthread_cond_broadcast(激活所有等待线程)
(4)清除条件变量:destroy;无线程等待,否则返回EBUSY
演示条件变量的例子:

Code
1 #include <stdio.h>
2 #include <pthread.h>
3
4 pthread_mutex_t mutex;
5 pthread_cond_t cond;
6 void *thread1(void *arg)
7 {
8 pthread_cleanup_push(pthread_mutex_unlock,&mutex);
9 //提供函数回调保护
10 while(1){
11 printf("thread1 is running\n");
12 pthread_mutex_lock(&mutex);
13 pthread_cond_wait(&cond,&mutex);
14 printf("thread1 applied the condition\n");
15 pthread_mutex_unlock(&mutex);
16 sleep(4);
17 }
18 pthread_cleanup_pop(0);
19 }
20
21 void *thread2(void *arg)
22 {
23 while(1){
24 printf("thread2 is running\n");
25 pthread_mutex_lock(&mutex);
26 pthread_cond_wait(&cond,&mutex);
27 printf("thread2 applied the condition\n");
28 pthread_mutex_unlock(&mutex);
29 sleep(1);
30 }
31 }
32 int main()
33 {
34 pthread_t thid1,thid2;
35 printf("condition variable study!\n");
36 pthread_mutex_init(&mutex,NULL);
37 pthread_cond_init(&cond,NULL);
38 pthread_create(&thid1,NULL,(void*)thread1,NULL);
39 pthread_create(&thid2,NULL,(void*)thread2,NULL);
40 do{
41 pthread_cond_signal(&cond);
42 }while(1);
43 sleep(20);
44 pthread_exit(0);
45 return 0;
46
3.异步信号(只有一个线程收到异步信号)
1 int pthread_kill(pthread_t thread,int signum);
2 int pthread_sigmask(int how,const sigset_t *newmask,const sigset_t *oldmask);
3 int sigwait(const sigset_t *set,int *sig);//等待指定信号到来,并存入*sig
六.出错处理
1.错误检查(要先令errno=0);
2.错误码(man errno)
3.错误提示信息perror(const char *message),char *strerror(int errno);