文章目录
回顾
前面有使用过异步IO(用signal函数、fcntl函数)、阻塞式IO(select、poll)来处理这个并发实践,要读键盘鼠标。
当然也可以使用fork,创建父子进程,然后再父子进程里面分别去读键盘鼠标。
**多进程的优点:**可以实现并发情况的处理
**多进程的缺点:**进程间的切换需要的断点保护与恢复开销比较大,而且进程之间是fork出来的话就相互独立的,可以说,所以通信麻烦,效率低。
所以,出现了线程。线程可以去优化这些问题。
线程的特性:
1.解决多任务
2.线程间切换,通信效率比进程高
3.多线程在多核cpu里面有优势
因为线程是在一个进程里面的,一个进程里面直接用全局变量去交换数据(通信)就会很方便。
线程可以说是一种轻量级的进程。
线程有自己的栈。
创建与回收
pthread_create
SYNOPSIS
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
Compile and link with -pthread.
这是pthread_create的原型。
注意下面那句Compile and link with -pthread. compile–编译
编译和链接都是要加上 -pthread
之前都没注意这句话,都是看课程讲解的时候说要加-pthread的,其实很多东西手册上就有提及,但是就没注意,或者说手册上没有一句话是多余的,只是自己当时的着重点在于函数的返回值,传参等等。所以还是要仔细观察。
pthread_create的作用是啥呢?
The pthread_create() function starts a new thread in the calling process.
The new thread starts execution by invoking start_routine();
arg is passed as the sole argument of start_routine().
在进程里面创建一个新的线程,新的线程通过召唤(哈哈哈 调用)原型里面的start_routine()函数来执行的,arg是调用的那个函数的唯一传参。
所以strat_routine()是挺关键的
在man手册里面查pthread_t ,只有原型和例程里面有,
例程里面是直接用pthread_t 去定一个新的变量thread_id ,这个thread_id是由pthread_create来返回的。
attr呢?
If attr is NULL, then the thread is created with default attributes.
也就是说attr一般设置NULL即可,具体怎么配置属性我也不懂,可能真的接触到别人的代码再仔细研究吧。
pthread_join
NAME
pthread_join - join with a terminated thread
SYNOPSIS
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
Compile and link with -pthread.
The pthread_join() function waits for the thread specified by thread to terminate.
pthread_join的作用是等待子线程被回收的,主线程指定了某个子线程的thread_id,然后就去终止它,应该是这样子理解的。
retval设置为NULL,如果不是NULL的话,pthread_join会复制目标线程结束的状态到rerval这个void * 类型的指针指向的地方,这是个二重指针,我试了好像不咋懂,是能返回一个奇奇怪怪的值,后面用到再研究,现在先传NULL即可。
pthread_detach
NAME
pthread_detach - detach a thread
SYNOPSIS
#include <pthread.h>
int pthread_detach(pthread_t thread);
Compile and link with -pthread.
pthread_detach的作用是用来分离这个子线程。这么说就不用主线程去理它了,在网上看其他的博客说
它的作用是由系统来回收线程所占用资源。
线程取消
pthread_cancel
NAME
pthread_cancel - send a cancellation request to a thread
SYNOPSIS
#include <pthread.h>
int pthread_cancel(pthread_t thread);
他就是发一个取消请求给线程,看他取消不取消。
这个取消与否又跟下面的 cancel state和cancel type有关。
pthread_setcancel state和 pthread_setcancel type
NAME
pthread_setcancelstate, pthread_setcanceltype - set cancelability state and type
SYNOPSIS
#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);
Compile and link with -pthread.
state 的:
PTHREAD_CANCEL_ENABLE (默认设置的)
PTHREAD_CANCEL_DISABLE
type 的:
PTHREAD_CANCEL_DEFERRED(默认的)
PTHREAD_CANCEL_ASYNCHRONOUS
具体看man手册啦
线程退出(退出机制)
pthread_exit
pthread_exit - terminate calling thread
SYNOPSIS
#include <pthread.h>
void pthread_exit(void *retval);
Compile and link with -pthread.
DESCRIPTION
The pthread_exit() function terminates the calling thread and returns a value via retval that (if the
thread is joinable) is available to another thread in the same process that calls pthread_join(3).
这么 一看之前的pthread_join的retval原来是跟这个有关的。
但是我学的时候这边是直接传NULL,因为joind的retval也是传的NULL。
pthread_cleanup_push和pthread_cleanup_pop
push和pop是相互对应的。
应该是锁上和解锁之类的,用的比较少,讲的时候也提及了一下,看man手册好像也不怎么懂,等以后遇到实际代码再补充吧
线程同步
信号量
sem_init
sem_post
sem_wait
sem_destory
互斥锁
条件
待续。。。。。。。。。。