多线程一直接触,这次系统学习一蛤。

多线程目的是在单进程环境下执行多个任务。一个进程中的所有线程都可以访问该进程的组成部件,如文件描述符和内存。

单个资源在多个用户间共享,就必须处理一致性问题。

同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。

但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。

通过__thread关键字是GCC内置的线程局部存储设施,存储效率堪比全局变量,它保证该变量在每个线程中都有独立的实体,互不干扰

1.线程标识

每个线程有一个线程ID,并且这个ID只有在它所属的进程上下文中才有意义。

#include

pthread_t pthread_self(void);//获取当前线程的线程ID

#include

int pthread_equal(pthread_t tid1,pthread_t tid2);

//相等返回非0

//否则返回0

pid_t用来标志进程,是一个非负整数,而pthread_t则有可能是一个结构体(取决于实现)。

因此,在调用pthread_equal的时候,参数必须严格是pthread_t类型的变量,否则将会出现未定义的行为:

The pthread_equal() function shall return a non-zero value if t1 and t2 are equal; otherwise, zero shall be returned.

If either t1 or t2 are not valid thread IDs, the behavior is undefined.

2.创建线程

#include

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

pthread_t * thread指向线程创建成功时线程id所在的内存单元

pthread_attr_t * attr创建时属性

start_routine即run in thread回调,这是一个函数指针,指向函数返回void* 参数是void*

void *arg即run in thread回调中的参数

3.线程终止

如果进程中的任意线程调用了exit、_Exit、_exit函数,那么整个进程就会终止。

如果终止进程,则发送到线程的信号就会终止整个进程。

通过在线程中调用exit系列函数发现,确实主进程也随着退出,那么如何优雅地退出?

1.直接返回 return

2.被其他线程取消

3.线程自己调用pthread_exit

而通过pthread_join则可以知道return或者pthread_exit的状态码

#include

void pthread_exit(void *retval);

#include

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

另外,在APUE中提到一个很重要的点,使用pthread_exit返回的变量不能是栈上变量,

我们知道每个线程有自己的栈,当某一个线程pthread_exit返回后,栈空间可能被另外的线程所覆盖

为了解决这个问题,我们可以使用全局变量和malloc函数分配的堆变量

下面这个代码测试了上述所有函数,详见github

//thread_exit.c

void *thread1(void *arg)

{

pthread_t *tid1=(pthread_t*)(arg);

int ret = pthread_equal(*tid1,pthread_self());

printf("in thread1 tid = %lu, ret is %d\r\n",(unsigned long)pthread_self(),ret);

return ((void*)2);

}

void *thread2(void *arg)

{

pthread_t *tid1=(pthread_t*)(arg);

int *a= (int *)malloc(sizeof(int));

printf("in thread2 pointer %p\r\n",a);

*a=5;

int ret = pthread_equal(*tid1,pthread_self());

printf("in thread2 tid = %lu,ret is %d\r\n",(unsigned long)pthread_self(),ret);

pthread_exit((void*)a);

}

int main(void )

{

pthread_t tid1;

pthread_t tid2;

int ret;

ret = pthread_create(&tid1,NULL,thread1,&tid1);

assert(ret==0);

ret = pthread_create(&tid2,NULL,thread2,&tid1);//test

assert(ret==0);

printf("main thread: %lu\r\n",(unsigned long)pthread_self());

void * status;

pthread_join(tid1,&status);

printf("thread %lu exit status is %ld\r\n",(unsigned long)tid1,(long)status);

int *fuck;

pthread_join(tid2,(void*)&fuck);

printf("======%d\r\n",*fuck);

printf("in main pointer %p\r\n",fuck);

free(fuck);//malloc in thread

//printf("thread %lu exit status is %d\r\n",(unsigned long)tid2,*(int *)status);

printf("main thread exit\r\n");

return 0;

}

linux tid为2的线程,Linux 线程Pthread(一)创建、终止、获取TID相关推荐

  1. linux 线程--内核线程、用户线程实现方法

    Linux上进程分3种,内核线程(或者叫核心进程).用户进程.用户线程 内核线程拥有 进程描述符.PID.进程正文段.核心堆栈 当和用户进程拥有相同的static_prio 时,内核线程有机会得到更多 ...

  2. linux创建线程未定义,Linux中未定义的对p线程_CREATE的引用

    Linux中未定义的对p线程_CREATE的引用#include #include #define NUM_THREADS     5void *PrintHello(void *threadid){ ...

  3. Linux系统编程---14(回收子线程,回收多个子线程,线程分离,杀死线程)

    回收子线程 pthread_join 函数 阻塞等待线程退出,获取线程退出状态 其作用,对应进程中 waitpid() 函数. int pthread_join (pthread_t thread,v ...

  4. Linux系统编程---13(线程控制函数,创建线程,循环创建多个线程,线程间共享全局变量)

    线程控制 操作系统并没有提供创建线程的系统调用接口,因此大佬们封装了一个线程的接口库实现线程控制.意为着用户创建线程都使用的是库函数(所以有时候我们说创建的线程是一个用户态线程,但是在内核中对应有一个 ...

  5. Linux应用编程基础04:Linux线程编程

    目录 1. 线程概念与模型 2. 线程实现方式 2.1 内核级线程 2.2 用户级线程 2.3 组合式线程 3. 线程标识 3.1 概念与实现 3.2 相关函数 3.2.1 pthread_equal ...

  6. linux 进程和线程或线程和线程之间通过管道通信(pipe)

    linux 进程和线程或线程和线程之间通过管道通信(pipe) 转自:http://blog.csdn.net/robertkun/article/details/8095331 线程间通信: [cp ...

  7. linux 下的进程创建线程,Linux线程 之 线程 线程组 进程 轻量级进程(LWP)

    线程是有栈的,我们知道,普通的一个进程,它的栈空间是8M,我们可以通过ulmit -a查看: stack size (kbytes, -s) 8192 线程也不例外,线程也是需要栈空间的这句话是废话, ...

  8. Linux服务器查看带宽,进程和线程

    Linux服务器上监控网络带宽的常用命令 监控总体带宽使用 ――nload.bmon.slurm.bwm-ng.cbm.speedometer和netload 监控总体带宽使用(批量式输出)――vns ...

  9. 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)

    文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...

最新文章

  1. 11-flutter事件监听
  2. 使用组策略部署exe软件
  3. [改善Java代码]覆写equals方法必须覆写hashCode方法
  4. 20220208--CTF MISC--两道简单的MISC题目
  5. elasticsearch存储空间不足导致索引只读,不能创建
  6. phpStrom编辑器常用功能教程
  7. linux-bzip2压缩
  8. 怎样快速运用KeyShot 6 鼠标视图操作
  9. HIVE 的笛卡尔积on无条件
  10. 程序员应该具备哪些素质
  11. JSP注册验证功能的实现
  12. zqoj 1819: 加加加!(油) 【水题】【郑大校赛】
  13. day0学习开始,起于markdown
  14. signature=4a882a48c4a4b2b41835e11b6fafa69f,ABB 38SC980002R375
  15. zookeeper初步
  16. node.js毕业设计安卓校园代办助手app(程序+APP+LW)
  17. 21级计科专业计算机组成原理实验一报告
  18. 刘汝佳 9.2.1 硬币问题
  19. 移动端事件(touchstart+touchmove+touchend)
  20. 小米电视ES65 2022款 评测

热门文章

  1. 第一批做移动开发的程序员,现在怎么样了?
  2. 龙飞船再次发射成功!马斯克无缘现场,因疑似感染新冠……
  3. Python自动化办公 | 补写178份Word日报!
  4. 阿里巴巴成立云原生技术委员会,云原生升级为阿里技术新战略!
  5. TIOBE 9 月编程语言:C++ 突起、Java 流行度下降
  6. 全国大学生数学建模竞赛中,哈工大被禁用 MATLAB!
  7. 紧急通知:招募 2000 名 IT 人学英语,免费培训!
  8. 23 岁创业,28 岁成为福布斯亚洲青年领袖,这个“刷脸的男人”有点牛
  9. 以正确的方式招募数据科学家!
  10. VUE 响应式原理源码:带你一步精通 VUE | 原力计划