多线程编程

来源:互联网 发布:淘宝一颗星是怎么来的 编辑:程序博客网 时间:2024/06/04 17:49

1.线程的概念

线程是计算机中独立运行的最小单位,运行时占用很少的系统资源。可以把线程看成是操作系统分配CPU时间的基本单元。一个进程可以拥有一个至多个线程。它线程在进程内部共享地址空间、打开的文件描述符等资源。同时线程也有其私有的数据信息,包括:线程号、寄存器(程序计数器和堆栈指针)、堆栈、信号掩码、优先级、线程私有存储空间。

2.线程和进程的区别

线程通常叫做轻型的进程。线程是在共享内存空间中并发执行的多道执行路径,他们共享一个进程的资源。线程和进程比起来很小。

3.线程的优点

1) 提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。
2) 使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。
3) 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。

4.创建线程

 #include <pthread.h>int pthread_create(pthread_t *thread,pthread_attr_t *attr,void *(*start_routine)(void *),void *arg);pthread_t pthread_self(void);int pthread_equal(pthread_t thread1,pthread_t thread2);int pthread_once(pthread_once_t *once_control,void(*init_routine)(void));

Linux系统支持POSIX多线程接口,称为pthread。编写linux下的多线程程序,需要包含头文件pthread.h,链接时需要使用库libpthread.a。
如果在主线程里面创建线程,程序就会在创建线程的地方产生分支,变成两个部分执行。线程的创建通过函数pthread_create来完成。成功返回0。
参数:
thread: 参数是一个指针,当线程成功创建时,返回创建线程ID。
attr: 用于指定线程的属性
start_routine: 该参数是一个函数指针,指向线程创建后要调用的函数。
arg: 传递给线程函数的参数。

5.线程退出

第一通过return从线程函数返回,
第二种通过调用pthread_exit()函数使线程退出。
需要注意的地方:一是,主线程中如果从main函数返回或是调用了exit函数退出主线程,则整个进程终止,此时所有的其他线程也将终止。另一种是,如果主线程调用pthread_exit函数,则仅仅是主线程消亡,进程不会结束,其他线程也不会结束,知道所有的线程都结束时,进程才结束。

6.通过一个线程让另外一个线程退出

调用pthread_cancel函数将导致tid所指向的线程终止运行。但是,一个线程可以选择忽略其它线程控制该线程何时退出。注意,该函数并不等待线程终止,它仅仅提出要求

7.什么情况会发生线程死锁,如何避免死锁

如果一个线程对mutex加两次锁则显然会导致死锁。 死锁可以通过控制加锁的顺序来避免。有两个mutex A和B,如果所有的线程总是先对A加锁再对B加锁就不会产生死锁。但实际应用中可能很难保证这种顺序加锁的方式,这种情况下,可以使用pthread_mutex_trylock来避免死锁的发生。

8.条件变量的作用

条件变量是线程可用的另外一种同步机制。条件变量给多个线程提供了一个会合的场所。条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定条件的发生。条件本身是由互斥量保护的。线程在改变状态前必须首先锁住互斥量,其它线程在获得互斥量之前不会觉察到这种变化。

9.互斥锁

(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下互斥锁不占用资源内存

10.条件变量

(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

原创粉丝点击