线程创建函数与实例(附加一重二重指针)

1  线程常见函数

1.1  线程创建于回收

(1)pthread_create    主线程用来创造子线程

(2)pthread_join        主线程用来等待(阻塞)回收子线程

(3)pthread_detach   主线程用来分离子线程,分离后主线程不必再去回收子线程

小结:线程函数创建的线程,就是里面函数指针指向的函数体,整个函数是一个线程,里面定义,申请的内存资源,当这个线程执行完,可以在主线程main中使用pthread_join回收内存资源,或者用pthread_detach分离出去。

1.2  线程终止

(1) pthread_cancel                    一般都是主线程调用该函数去取消(让它赶紧死)子线程

(2)pthread_setcancelstate 子线程设置自己是否允许被取消

(3)pthread_setcanceltype        子线程允许被取消这个后这个函数才有用,他是被取消的方式,什么情况才死

1.3 线程函数退出相关

(1)pthread_exit与return退出     pthread_exit的返回值最后给pthread_join,就是它返回的

(2)pthread_cleanup_push         线程清理压栈相关

(3)pthread_cleanup_pop          清理弹栈相关

小结:(1)不能用exit(0)退出一个线程,他是整个进程的推出函数,pthread_exit的返回的是一个一重指针,所以pthread_join要用一个二重指针来接收它,才能在pthread_join函数体里面对这个一重指针本身进行操作,而不是对一重指针指向的变量操作,pthread_join要操作的是,这个一重指针。操作变量,我们用一重指针接收,操作指针我们用二重指针接收

            (2)pthread_cleanup_push,防止线程上锁之后,正常线程处理完后,会被释放锁,但是上锁后,被主线程pthread_cancel取消了,而锁还没有释放,这时用pthread_cleanup_push解开锁(里面绑定了一个开锁函数),放在上锁函数后面,pthread_cleanup_pop用来接应push,详细见视频位置

1.4 获取线程id

(1)pthread_self    获取线程ID,没有进程id重要。

2  线程创建过程

--在进程中只有一个控制线程时

--程序开始运行的时候每个进程只有一个线程,它是以单线程方式启动的,在创建多个线程以前,进程的行为与传统的进程没有区别
--gcc在链接的时候需要增加-lpthread选项(pthread是共享库文件)。
--创建一个线程调用pthread_create函数。
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
如果pthread_create成功返回,有thread指向的内存单元被设置为新创建线程的线程ID。
attr参数用于定制各种不同的线程属性。
新创建的线程从start_routine函数地址开始执行,该函数只有一个void *参数,
如果需要向start_routine函数传递多个参数,就需要把这些参数放到一个结构中,然后把这个结构的地址作为void *传入。
线程创建的时候不能保证哪个先运行。
pthread_create函数成功返回0,失败返回非0,并且更新errno。
--注意:每个线程都拥有一份errno副本,不同的线程拥有不同的errno


3 线程终止

--任一线程调用了exit函数,整个进程就会终止。

--如果信号默认动作是终止进程,那么信号发送到该进程,整个进程也会被终止。
单个线程通过以下三种方式退出
--线程只是从启动函数中返回,返回值是线程的退出码
--线程可以被同一进程中的其他线程取消。
--线程调用pthread_exit。
void pthread_exit(void * arg);
arg是个无类型指针,该指针会被其他线程调用pthread_join捕捉。
在线程的子函数中调用pthread_exit()函数,线程也会退出,这点跟exit()函数相同。
线程之间是异步的,无法确定哪个线程先执行。
进程内的信号捕捉一般在控制线程内进行

pthread_create()函数的第四个参数对应回调函数的参数

猜你喜欢

转载自blog.csdn.net/qq_40334837/article/details/80300790