【线程】线程基本函数

一、pthread_self函数

功能:获取线程ID。

pthread_t pthread_self(void);
  • 线程ID:pthread_t类型,本质:在Linux为无符号整数(%lu),其他系统可能是结构体实现
  • 线程ID是进程内部识别标志。(两个进程间,线程ID允许相同)

注意:不应使用全局变量pthread_t tid,在子线程通过pthread_create传出参数来获取线程ID,而应使用pthread_self.

 

二、pthread_create函数

功能:创建一个新线程

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

参数:

  • pthread_t:当前Linux可理解为:typedef unsigned long int pthread_t;
  • 参数1:传出参数,保存系统为我们分配好的线程ID
  • 参数2:通常传NULL,表示使用线程默认属性。若想使用具体属性也可以修改该参数。
  • 参数3:函数指针,指向线程主函数(线程体),该函数运行结束,则线程结束。
  • 参数4:线程执行期间所使用的参数。

 

1. 测试代码:

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>void *thrd_func(void *arg)
{printf("In thread:thread id = %lu, pid = %u\n", pthread_self(), getpid());return NULL;
}int main(void)
{pthread_t tid;int ret; printf("In main 1: thread id = %lu, pid = %u\n", pthread_self(), getpid());ret = pthread_create(&tid, NULL, thrd_func, NULL);if(ret != 0) {fprintf(stderr, "pthread_create error: %s\n", sterror(ret));exit(1);}sleep(1);    printf("In main 2: thread id = %lu, pid =%u\n", pthread_self(), getpid());    return 0;
}

输出结果:

 

 

2. 测试代码:

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>void *thrd_func(void *arg)
{int i = (int) arg;sleep(i);printf("%dth thread: id = %lu, pid = %u\n", i+1, pthread_self(), getpid());return NULL;
}int main(void)
{pthread_t tid;int ret, i; for(i = 0; i < 5; i++) {ret = pthread_create(&tid, NULL, thrd_func, (void *)i);if(ret != 0) {fprintf(stderr, "pthread_create%s\n", strerror(ret));exit(1);}}sleep(i);return 0; //将当前进程退出 
}

输出结果:

 

 

 

三、线程与共享

注意:线程间共享全局变量!

【牢记】线程默认共享数据段、代码段等地址空间,常用的是全局变量,而进程间不共享变量,只能借助mmap。

线程共享资源:

  • 文件描述符
  • 每种信号的处理方式
  • 当前工作目录
  • 用户ID和组ID
  • 内存地址空间(.text/ .data/ .bss/heap/共享库)

线程非共享资源

  • 线程ID
  • 处理器现场和栈指针(内核栈)
  • errno变量
  • 信号屏蔽字

测试代码:

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>int var = 100;void *tfn(void *arg)
{var = 200;printf("thred\n");return NULL;
}int main(void)
{printf("At first var = %d\n", var);pthread_t tid;pthread_create(&tid, NULL, tfn, NULL);sleep(1);printf("after pthread_create, var = %d\n", var);return 0;} 

输出结果:

 

 

四、pthread_exit函数

功能:将单个线程退出

void pthread_exit(void *retval)  参数:retval表示线程退出状态,通常NULL

 

1. 测试代码:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int func(int a)
{pthread_exit(NULL);
}void *tfn(void *arg) 
{int i;i = (int)arg;sleep(i);if(i == 2)func(888);printf("I'am %dth thread, Thread_ID = %lu\n", i+1, pthread_self());pthread_exit(NULL);    
}int main() 
{int n = 5, i;pthread_t tid;for(i = 0; i < n; ++i) {pthread_create(&tid, NULL, tfn, (void*)i);}sleep(i);printf("I am main, and I am not a process, I'am a thread!\n""main_thread_ID = %lu\n", pthread_self());return 0;    
}

输出结果:

 

2. 测试代码:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int func(int a)
{return 0;
}void *tfn(void *arg) 
{int i;i = (int)arg;sleep(i);if(i == 2)func(888);printf("I'am %dth thread, Thread_ID = %lu\n", i+1, pthread_self());pthread_exit(NULL);    
}int main() 
{int n = 5, i;pthread_t tid;for(i = 0; i < n; ++i) {pthread_create(&tid, NULL, tfn, (void*)i);}sleep(i);printf("I am main, and I am not a process, I'am a thread!\n""main_thread_ID = %lu\n", pthread_self());return 0;    
}

 输出结果:

 

五、pthread_join函数

int pthread_join(pthread_t thread, void **retval);返回值:若成功,返回0,否则,返回错误编号

参数:

  • thread:线程ID(【注意】:不是指针);retval:存储线程结束状态

注意:

  • 调用该函数的线程将挂起等待,直到id为thread的线程终止状态。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:
  1. 如果thread线程通过return返回,retval所指向的单元存放的是thread线程函数的返回值。
  2. 若果thread线程被别的线程调用pthread_cancel异常终止掉,retval指向单元里存放的是常数PTHREAD_CANCELED。

 

1. 测试代码:

#include<pthread.h>
#include<stdlib.h>typedef struct 
{int a;int b;
} exit_t; void *tfn(void *arg)
{exit_t *ret;ret = (exit*)malloc(sizeof(exit_t));ret->a = 100;ret->b = 300;pthred_exit((void *) ret);
}
int main()
{pthread_t tid;exit_t *retval;pthread_create(&tid, NULL, tfn, NULL);pthread_join(tid, (void**)&retval);  /*调用pthread_join可以获取线程的退出转态*/ printf("a = %d, b = %d\n", retval->a, retval->b);return 0;} 

输出结果:

 

2. 测试代码:

#include<stdio.h>
#include<string.h> 
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>typedef struct {int ch;int var;char str[64];
}exit_t;void *thrd_func(void *arg)
{exit_t *retval = (exit_t *)arg;retval->ch = 'm';retval->var = 200;strcpy(retval->str, "my thread\n");pthread_exit((void*) retval); 
}
int main()
{pthread_t tid;int ret;exit_t *retval = (exit_t *)malloc(sizeof(exit_t));printf("In main 1: thread id = %lu, pid = %u\n", pthread_self(), getpid());ret = pthread_create(&tid, NULL, thrd_func, (void*)retval);if(ret != 0) {fprintf(stderr, "pthread_create error: %s\n", strerror(ret));exit(1);}pthread_join(tid, (void**)&retval);printf("ch = %c, var = %d, str = %s\n", retval->ch, retval->var, retval->str);free(retval);pthread_exit((void *)1);
}

输出结果:

 

测试代码:

#include<stdio.h>
#include<string.h> 
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>typedef struct {int ch;int var;char str[64];
}exit_t;void *thrd_func(void *arg)
{exit_t *retvar = (exit_t *)malloc(sizeof(exit_t));retvar->ch = 'm';retvar->var = 200;strcpy(retvar->str, "my thread\n");pthread_exit((void*) retvar); 
}
int main()
{pthread_t tid;int ret;exit_t *retval;printf("In main 1: thread id = %lu, pid = %u\n", pthread_self(), getpid());ret = pthread_create(&tid, NULL, thrd_func, NULL);if(ret != 0) {fprintf(stderr, "pthread_create error: %s\n", strerror(ret));exit(1);}pthread_join(tid, (void**)&retval);printf("ch = %c, var = %d, str = %s\n", retval->ch, retval->var, retval->str);free(retval);pthread_exit((void *)1);
}

输出结果:

 

3. 测试代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>int var = 100;void *tfn(void *arg)
{int i;i = (int) arg;sleep(i);if(i == 1) {var = 333;printf("var = %d\n", var);return (void*) var;} else if(i == 3) {var = 777;printf("I'm %dth pthread, pthread_id = %lu\n var = %d\n", i+1, pthread_self(), var);pthread_exit((void*)var);     } else {printf("I'm %dth pthread, pthread_id = %lu\n var = %d\n", i+1, pthread_self(), var);pthread_exit((void*)var);}return NULL;
}int main()
{int i;pthread_t tid[5];int *ret[5];for(i = 0; i < 5; ++i) {pthread_create(&tid[i], NULL, tfn, (void*)i);}for(i = 0; i < 5; ++i) {pthread_join(tid[i], (void**)&ret[i]);printf("----------%d's ret = %d\n", (int)ret[i]);        }printf("I'm  main pthread tid = %lu\t var = %d\n", pthread_self(), var);sleep(i);return 0;    
}

输出结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一条正确的Java职业生涯规划,顺利通过阿里Java岗面试

珍藏版&#xff08;1&#xff09;——Mybatis入门 1.什么是MyBatis 2.为什么我们要用Mybatis? 3.Mybatis快速入门 3.1 导入开发包 3.2准备测试工作 3.3 创建mybatis配置文件 3.4 编写工具类测试是否获取到连接 3.5 创建实体与映射关系文件 3.6 编写DAO 4.Mybatis工作…

一次违反常规的Java大厂面试经历,系列教学

第一部分 Java相关以及答案 答案 第二部分算法跟编程 第三部分html&JavaScript&ajax部分 答案 第四部分Javaweb部分 答案 第五部分数据库部分 答案 第六部分XML部分 答案 第七部分.流行的框架与新技术 答案 第八、九部分.软件工程与设计模式以及j2ee部分 最后 笔者…

一次违反常规的Java大厂面试经历,重难点整理

目录 Kafka的基本介绍Kafka的设计原理分析Kafka数据传输的事务特点Kafka消息存储格式副本&#xff08;replication&#xff09;策略Kafka消息分组&#xff0c;消息消费原理Kafak顺序写入与数据读取消费者&#xff08;读取数据&#xff09; Kafka的基本介绍 Kafka是最初由Lin…

一步搞定你疑惑的数据结构与算法系列,原理+实战讲解

蚂蚁金服一面&#xff1a; 下午杭州的电话&#xff0c;问有没有空&#xff0c;果断有空&#xff0c;虽然感觉略显紧张&#xff0c;有点懵逼。 面试的题目&#xff1a; HashMap和Hashtable的区别实现一个保证迭代顺序的HashMap说一说排序算法&#xff0c;稳定性&#xff0c;复…

互斥量(互斥锁)

一、互斥量mutex Linux提供一把互斥锁mutex(也称之为互斥量)每个线程在对资源操作前都尝试先加锁&#xff0c;成功加锁才能操作&#xff0c;操作结束后解锁。资源还是共享的&#xff0c;线程间也还是竞争的&#xff0c;但通过锁将资源的访问变为互斥操作&#xff0c;而后与时间…

一眼就能看懂的Java自学手册,终局之战

珍藏版&#xff08;1&#xff09;——Mybatis入门 1.什么是MyBatis 2.为什么我们要用Mybatis? 3.Mybatis快速入门 3.1 导入开发包 3.2准备测试工作 3.3 创建mybatis配置文件 3.4 编写工具类测试是否获取到连接 3.5 创建实体与映射关系文件 3.6 编写DAO 4.Mybatis工作…

Java虚拟机学习集锦是我攒来的,带你碾压面试官!

1. 一致性&#xff08;Consistency&#xff09; 一致性&#xff08;Consistency&#xff09;是指多副本&#xff08;Replications&#xff09;问题中的数据一致性。可以分为强一致性、顺序一致性与弱一致性。 1.1 强一致性&#xff08;Strict Consistency&#xff09; 也称为…

Java虚拟机学习集锦是我攒来的,看这篇文章准没错!

一面 介绍一下自己 问项目经历, 聊"数据同步" 接着聊上了 K8S 的项目 有没有什么钻研得比较深得技术&#xff1f;&#xff08;大佬&#xff1a;kubernetes, golang, prometheus, java&#xff09; kubernetes 的架构是怎么样的? 这个问题很大&#xff0c;拆成 …

文件描述符、函数open和openat

文件描述符 pcb&#xff1a;结构体一个进程有一个文件描述符&#xff1a;1024文件描述符&#xff1a;寻找磁盘文件函数open和openat 函数原型&#xff1a; include<sys/stst.h> #include<fcntl.h>int open(const char *pathname, int flags); int open(const ch…

Java这些高端技术只有你还不知道,移动架构师成长路线

并发编程共享模型篇 并发编程概览进程与线程Java线程共享模型之管程共享模型之内存共享模型之无锁共享模型之不可变共享模型之工具 共享模型之管程 原理之 Monitor(锁) 原理之伪共享 模式篇—正确姿势 同步模式之保护性智停同步模式之Blking同步模式之顺序控制异步模式之生产…

函数read、write、lseek

函数原型&#xff1a; #include<unistd.h> ssize_t read(int fd, void *buf, size_t count);返回值&#xff1a;读到的字节数&#xff0c;若已到文件尾&#xff0c;返回0&#xff1b;若出错&#xff0c;返回-1 参数&#xff1a; fd&#xff1a;函数open的返回值buf&a…

Java这些高端技术只有你还不知道,薪资翻倍

正文 我的第一份工作是在一家外企&#xff0c;当时抱着“逃离”上海的想法去了二线城市的分公司&#xff0c;但是管理文化氛围跟总部几乎都是一样的&#xff0c;这份工作经历对我后面的工作不论是做事风格、习惯上还是思考问题的方式方法上都有很大的影响。后面陆续进入国企&a…

函数dup和dup2

函数原型&#xff1a; #include<unistd.h> int dup(int oldfd);返回值&#xff1a;若成功&#xff0c;返回新的文件描述符&#xff1b;若出错&#xff0c;返回-1 参数&#xff1a; oldfd&#xff1a;要复制的文件描述符dup调用成功&#xff1a;有两个文件描述符指向同…

Java进阶面试资料无偿分享!真香系列

8-22 投递简历 8-24 一面&#xff08;大概1h50min&#xff09; 0、currenthashmap怎么扩容的&#xff1f;fwn为什么固定hash -1&#xff0c;这样设计有什么好处&#xff1f;帮助扩容是发生在什么阶段?读线程和写线程都会帮助扩容吗&#xff1f;扩容的时候任务具体怎么协调的&…

Java通用流行框架大全,绝对干货

Java如何入门&#xff1f; 1、建立好开发环境 首先建立好开发环境非常重要&#xff0c;工欲善其事&#xff0c;必先利其器。做任何开发&#xff0c;首先就是要把这个环境准备好&#xff0c;之后就可以去做各种尝试&#xff0c;尝试过程中就能逐渐建立信心。初学者往往在环境配…

Java集合类中绝对占有一席之地的List,涨薪7K!

一、先来解读&#xff1a;23种设计模式要点 1.单例模式&#xff08;Singleton Pattern&#xff09; 2.工厂模式 3.抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09; 4.模板方法模式&#xff08;Template Method Pattern&#xff09; 5.建造者模式&#xff08;Bu…

Java面试10大知识点总结宝典助你通关!已拿意向书!

Java基础 1.Java语言的三大特性 2.Java语言主要特性 3. JDK和JRE有什么区别 4.Java基本数据类型及其封装类 5.如果main方法被声明为private会怎样? 6.说明- -下public static void main(String argsQ])这段声明里每个关键字的作用 7.与equals的区别 8.Object有哪些公用方法 9.…

互斥锁、条件变量

一、互斥锁 1. 函数原型&#xff1a; pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); pthread_mutex_destroy(pthread_mutex_t *mutex); 分析&#xff1a; pthread_mutex_t 类型&#xff0c;其本质是一个结构体&#xf…

Java面试你必须要知道的那些知识,深夜思考

如何提升自己的实力&#xff1f; Step 1&#xff1a;梳理自己的知识 对照下面这份学习大纲&#xff0c;梳理出自己的知识盲区&#xff0c;这份大纲里面的技术点完全对标P7岗的主流技术&#xff0c;因此这是一份很好的知识大纲笔记。 Step 2&#xff1a;查漏补缺&#xff0c;夯…

Java面试你必须要知道的那些知识,面试建议

二、面试题 面&#xff1a;考你几个红黑树的知识点&#x1f980; 红黑树的数据结构都用在哪些场景&#xff0c;有什么好处&#xff1f;红黑树的时间复杂度是多少&#xff1f;红黑树中插入新的节点时怎么保持平衡&#xff1f; 面&#xff1a;2-3树都是不没看&#xff0c;回去…