Linux 线程

线程概念:

进程:有独立的 进程地址空间。有独立的 pcb。 是分配资源的最小单位。

线程:有独立的 pcb。没有独立的进程地址空间。 是执行的最小单位。

查看线程号:ps -Lf 所查看的pid

轻量级进程(light-weight process),也有 PCB,创建线程使用的底层函数和进程一样,都是clone 。从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB 中指向内存资源的三级页表是相同的。进程可以蜕变成线程,线程可看做寄存器和栈的集合。

线程独享栈空间,共享全局变量。

创建线程pthread_create

int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*start_rountn)(void *), void *arg);

参 1:传出参数,表新创建的子线程 id。

参 2:线程属性。传 NULL 表使用默认属性。

参 3:子线程回调函数。创建成功,ptherad_create 函数返回时,该函数会被自动调用。

*与创建进程不一样,线程只会执行参3的函数,不会继续执行主线程之后的代码。

参 4:参 3 的参数。没有的话,传 NULL。

返回值:成功:0。

失败:errno。

获取线程 id pthread_self

pthread_t pthread_self(void); 线程 id 是在进程地址空间内部,用来标识线程身份的 id 号。

返回值:本线程 id。

线程退出 pthread_exit

void pthread_exit(void *retval); 退出当前线程。

retval:退出值。 无退出值时,NULL。即调用函数的返回值。

*线程退出的三种方式:在线程函数中return;用pthread_exit终止自己;用pthread_cancel终止其他。

*由于主线程可能先于子线程结束,所以子线程的输出可能不会打印出来,当时是用主线程 sleep 等待子线程结束来解决的。现在就可以使用 pthread_exit 来解决了。方法就是将 return 0 替换为 pthread_exit,只退出当先线程,不会对其他线程造成影响。

线程回收 pthread_join

阻塞当前线程,等待对应线程执行结束后回收线程。

int pthread_join(pthread_t thread, void **retval);

thread: 待回收的线程 id。

retval:传出参数。 回收的那个线程的退出值。线程异常结束,值为 -1。

返回值:成功:0。

失败:errno。

线程终止 pthread_cancel

杀死一个线程。 需要到达取消点(保存点)。

int pthread_cancel(pthread_t thread);

thread: 待杀死的线程 id。

返回值: 成功:0。

失败:errno。

如果,子线程没有到达取消点, 那么 pthread_cancel 无效。

我们可以在程序中,手动添加一个取消点。使用 pthread_testcancel();

成功被 pthread_cancel() 杀死的线程,返回 -1.使用 pthead_join 回收。

线程分离 pthread_detach

线程分离的本质是让主线程不join新线程,不关心返回值,从而让新线程退出的时候自动回收。

int pthread_detach(pthread_t thread);

thread: 待分离的线程 id。

返回值: 成功:0。

失败:errno。

线程分离后,系统会自动回收资源,用 pthread_join 去回收已经被系统回收的线程,那个线程号就是无效参数。

可以运用线程属性设置分离线程。

pthread_attr_t attr //创建一个线程属性结构体变量
pthread_attr_init(&attr); //初始化线程属性
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //设置线程属性为分离态
pthread_create(&tid, &attr, tfn, NULL); //借助修改后的 设置线程属性 创建为分离态的新线程
pthread_attr_destroy(&attr); //销毁线程属性

注意事项

1.主线程退出其他线程不退出,主线程应调用pthread_exitw

2.避免僵尸线程。pthread_join;pthread_detach;pthread_create指定分离属性,被join线程可能在join函数返回前就释放完自己的所有内存资源,所以不应当返回被回收线程栈中的值。

3. malloc和 mmap申请的内存可以被其他线程释放。

4.应避免在多线程模型中调用fork,除非马上 exec,子进程中只有调用fork的线程存在,其他线程在子进程中均pthread_exit。

5.信号的复杂语义很难和多线程共存,应避免在多线程引入信号机制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值