什么是进程?&&什么是线程?
进程是系统中程序执行和资源分配的基本单位。每个进程有自己的数据段、代码段和堆栈段。
线程通常叫做轻型的进程。线程是在共享内存空间中并发执行的多道执行路径,他们共享一个进程的资源。
线程和进程比起来很小,所以相对来说,线程花费更少的CPU资源。
通俗解释下线程:
1。单进程单线程:一个人在一个桌子上吃菜。
2。单进程多线程:多个人在同一个桌子上一起吃菜。
3。多进程单线程:多个人每个人在自己的桌子上吃菜。
多线程的问题是多个人同时吃一道菜的时候容易发生争抢,例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了。。。此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢。
如何来标识一个线程?
表示进程号的为pid_t类型,表示线程号的是pthread_t类型; pthread_t是一个结构体而不是整型;
使用pthread_equal确定两个线程号是否相等;
使用pthread_self函数来获取线程的ID;
线程创建
在进程被创建时,系统会为其创建一个主线程,而要在进程中创建新的线程,则可以调用pthread_create函数:
#include <pthread.h>
int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
参数说明:
- thread:指向pthread_create类型的指针,用于引用新创建的线程。
- attr:用于设置线程的属性,一般不需要特殊的属性,所以可以简单地设置为NULL。
- start_routine:传递新线程所要执行的函数地址。
- arg:新线程所要执行的函数的参数。
返回值:
调用如果成功,则返回值是0;如果失败则返回错误代码。
每个线程都有自己的线程ID,以便在进程内区分。线程ID在pthread_create调用时回返给创建线程的调用者;一个线程也可以在创建后使用pthread_self()调用获取自己的线程ID:
pthread_self (void);
线程退出
线程的退出方式有三种:
(1)执行完成后隐式退出;
(2)由线程本身显示调用pthread_exit 函数退出;
pthread_exit (void * retval);
(3)被其他线程用pthread_cance函数终止:
pthread_cancel (pthread_t thread);
如果一个线程要等待另一个线程的终止,可以使用pthread_join函数,该函数的作用是调用pthread_join的线程将被挂起直到线程ID为参数thread的线程终止:
pthread_join (pthread_t thread, void** threadreturn);
死锁
如果一个线程对mutex加两次锁则显然会导致死锁。 死锁可以通过控制加锁的顺序来避免。有两个mutex A和B,如果所有的线程总是先对A加锁再对B加锁就不会产生死锁。但实际应用中可能很难保证这种顺序加锁的方式,这种情况下,可以使用pthread_mutex_trylock来避免死锁的发生。
条件变量
条件变量是线程可用的另外一种同步机制。条件变量给多个线程提供了一个会合的场所。条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定条件的发生。条件本身是由互斥量保护的。线程在改变状态前必须首先锁住互斥量,其它线程在获得互斥量之前不会觉察到这种变化。