linux系统编程:线程原语
线程原语
线程概念
线程(thread),有时被称为轻量级进程(Lightweight Process,LWP)。是程序运行流的最小单元。一个标准的线程由线程ID。当前指令指针(PC),寄存器集合和堆栈组成。
url=CADJ4mxO_oQlyaraHnok4hzyrwmJ0DrnwBM48Y0Ck_7i6M5R6e08_fyYWj-pJdDZ2IQ6tJ2ClbKqyXWevBiSSK">线程。
在Linux shell下通过命令 $ ps -Lf pid 查看指定pid号下的全部线程。
线程之间的共享与非共享
这里的线程是指同一进程下的线程。
共享:
1.文件描写叙述符表
2.每种信号的处理方式
3.当前工作文件夹
4.用户ID和组ID
5.内存地址空间
非共享:
1.线程id
2.处理器现场和栈指针(内核栈)
3.独立的栈空间(用户空间栈)
4.errno变量
5.信号屏蔽字
6.调度优先级
线程原语
通过命令 $ man -k pthread 查看系统下与线程有关的全部函数。
一般的,把main函数称作主线程或主控线程,其他线程都称作是子线程。
创建线程
- #include <pthread.h>
- int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
pthread_t *thread:传递一个pthread_t变量地址进来,用于保存新线程的tid(线程ID)
const pthread_attr_t *attr:线程属性设置。如使用默认属性,则传NULL
void *(*start_routine)(void *):函数指针。指向新线程应该载入运行的函数模块
void *arg:指定线程将要载入调用的那个函数的參数
返回值:成功返回0,失败返回错误号。
曾经学过的系统函数都是成功返回0,失败返回-1。而错误号保存在全局变量errno中,而pthread库的函数都是通过返回值返回错误号,尽管每一个线程也都有一个errno,但这是为了兼容其他函数接口而提供的,pthread库本身并不使用它。通过返回值返回错误码更加清晰。
Compile and link with -lpthread.
typedef unsigned long int pthread_t; //在不同的系统中pthread_t可能会有不同的实现
结束线程
假设须要仅仅终止某个线程而不终止整个进程。能够有三种方法:
1.return。
这样的方法对主控线程不适用。从main函数return相当于调用exit。
2.一个线程能够调用pthread_cancel终止同一进程中的还有一个线程。
- #include <pthread.h>
- int pthread_cancel(pthread_t thread);
被取消的线程,退出值。定义在Linux的pthread库中常数PTHREAD_CANCELED的值是-1。能够在头文件pthread.h中找到它的定义:#define PTHREAD_CANCELED ((void *) -1)。也就是说,被pthread_cancel结束的线程,退出值,都是-1。
同一进程的线程间,pthread_cancel向还有一线程发终止信号。
系统并不会立即关闭被取消线程,仅仅有在被取消线程下次系统调用时,才会真正结束线程。
或调用pthread_testcancel,让内核去检測是否须要取消当前线程。
3.线程能够调用pthread_exit终止自己。
- #include <pthread.h>
- void pthread_exit(void *retval);
- void *retval:线程退出时传递出的參数。能够是退出值或地址,如是地址时,不能是线程内部申请的局部地址。
在不论什么地方调用exit,都会使整个进程退出。
线程id
- #include <pthread.h>
- pthread_t pthread_self(void);
- RETURN VALUE
- This function always succeeds, returning the calling thread’s ID.
在线程中使用pthread_self。获取线程id。
回收线程
- #include <pthread.h>
- int pthread_join(pthread_t thread, void **retval);
- pthread_t thread:回收线程的tid
- void **retval:接收退出线程传递出的返回值
- 返回值:成功返回0。失败返回错误号
同进程相似,线程退出后,相同须要进行回收,所以pthread_join相似于wait。调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的。总结例如以下:
- 假设thread线程通过return返回,retval所指向的单元里存放的是thread线程函数的返回值。
- 假设thread线程被别的线程调用pthread_cancel异常终止掉,retval所指向的单元里存放的是常数PTHREAD_CANCELED。
- 假设thread线程是自己调用pthread_exit终止的。retval所指向的单元存放的是传给pthread_exit的參数。
假设对thread线程的终止状态不感兴趣,能够传NULL给retval參数。
代码演示样例
使用return和pthread_exit结束进程
- //thread_exit.c
- #include <stdio.h>
- #include <unistd.h>
- #include <pthread.h>
- void *fun_1(void *argv)
- {
- printf("Hello %s,my thread id is %x\n", (char*)argv, pthread_self());
- sleep(1);
- //pthread_exit((void*)1);
- return (void*)1;
- }
- void *fun_2(void *argv)
- {
- printf("Hello %c, my thread id is %x\n", (char)argv, pthread_self());
- sleep(2);
- pthread_exit((void*)"David");
- }
- int main(void)
- {
- int *ret1;
- char *ret2;
- pthread_t tid1, tid2;
- pthread_create(&tid1, NULL, fun_1, (void*)"zhangxiang");
- pthread_create(&tid2, NULL, fun_2, (void*)'D');
- pthread_join(tid1, (void*)&ret1);
- pthread_join(tid2, (void*)&ret2);
- printf("thread %x exit with %x\n", tid1, ret1);
- printf("thread %x exit with %s\n", tid2, ret2);
- return 0;
- }
- $ gcc thread_exit.c -lpthread
- $ ./a.out
- Hello D, my thread id is 745e9700
- Hello zhangxiang, my thread id is 74fea700
- thread 74fea700 exit with 1
- thread 745e9700 exit with David
使用pthread_cancel终止还有一个线程
- //thread_cancel.c
- #include <stdio.h>
- #include <pthread.h>
- void *fun(void *argv)
- {
- printf("thread %x running\n", pthread_self());
- pthread_exit((void*)0);
- }
- int main(void)
- {
- pthread_t tid;
- void *ret;
- pthread_create(&tid, NULL, fun, NULL);
- pthread_join(tid, &ret);
- printf("thread %x exit with %d\n", tid, (int)ret);
- pthread_create(&tid, NULL, fun, NULL);
- pthread_cancel(tid);
- pthread_join(tid, &ret);
- printf("thread %x exit with %d\n", tid, (int)ret);
- return 0;
- }
- $ gcc thread_cancel.c -lpthread
- $ a.out
- thread 96da9700 running
- thread 96da9700 exit with 0
- thread 96da9700 running
- thread 96da9700 exit with -1
既能够在主线程中使用pthread_cancel终止子线程。也能够在子线程中终止还有一个子线程。
linux系统编程:线程原语的更多相关文章
- Linux系统编程——线程私有数据
在多线程程序中.常常要用全局变量来实现多个函数间的数据共享.因为数据空间是共享的,因此全局变量也为全部线程共同拥有. 測试代码例如以下: #include <stdio.h> #inclu ...
- linux系统编程--线程
安装线程man page,命令:sudo apt-get install manpages-posix-dev 线程概念 什么是线程 LWP:light weight process 轻量级的进程,本 ...
- Linux系统编程 —线程同步概念
同步概念 同步,指对在一个系统中所发生的事件之间进行协调,在时间上出现一致性与统一化的现象. 但是,对于不同行业,对于同步的理解略有不同.比如:设备同步,是指在两个设备之间规定一个共同的时间参考:数据 ...
- linux系统编程--线程同步
同步概念 所谓同步,即同时起步,协调一致.不同的对象,对“同步”的理解方式略有不同. 如,设备同步,是指在两个设备之间规定一个共同的时间参考: 数据库同步,是指让两个或多个数据库内容保持一致,或者按需 ...
- Linux系统编程 —线程属性
在之前的章节中,我们在调用pthread_create函数创建线程时,第二个参数(即线程属性)都是设为NULL,即使用默认属性.一般情况下,使用默认属性已经可以解决我们开发过程中的大多数问题. 但是, ...
- Linux 系统编程 学习:09-线程:线程的创建、回收与取消
Linux 系统编程 学习:09-线程:线程的创建.回收与取消 背景 我们在此之前完成了 有关进程的学习.从这一讲开始我们学习线程. 完全的开发可以参考:<多线程编程指南> 在Linux ...
- Linux 系统编程 学习:10-线程:线程的属性
Linux 系统编程 学习:10-线程:线程的属性 背景 上一讲我们介绍了线程的创建,回收与销毁:简单地提到了线程属性.这一讲我们就来具体看看,线程的属性. 概述 #include <pthre ...
- Linux 系统编程 学习:11-线程:线程同步
Linux 系统编程 学习:11-线程:线程同步 背景 上一讲 我们介绍了线程的属性 有关设置.这一讲我们来看线程之间是如何同步的. 额外安装有关的man手册: sudo apt-get instal ...
- Linux系统编程温故知新系列 --- 01
1.大端法与小端法 大端法:按照从最高有效字节到最低有效字节的顺序存储,称为大端法 小端法:按照从最低有效字节到最高有效字节的顺序存储,称为小端法 网际协议使用大端字节序来传送TCP分节中的多字节整数 ...
- 读书笔记之Linux系统编程与深入理解Linux内核
前言 本人再看深入理解Linux内核的时候发现比较难懂,看了Linux系统编程一说后,觉得Linux系统编程还是简单易懂些,并且两本书都是讲Linux比较底层的东西,只不过侧重点不同,本文就以Linu ...
随机推荐
- css 让背景图片不停旋转
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- sql server中扩展存储过程
--列出服务器上安装的所有OLEDB提供的程序 execute master..xp_enum_oledb_providers --得到硬盘文件信息 --参数说明:目录名,目录深度,是否显示文件 (少 ...
- 【转】AndroidStudio升到最新版本(3.1.2)之后
AndroidStudio升到最新版本(3.1.2)之后 暂时发现的需要大家注意的地方 1.androidstudio3无法导入moudle? 例如:我写了一个简单的项目,需要导入一个第三方的mo ...
- CCF CSP 201503-3 节日
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201503-3 节日 问题描述 有一类节日的日期并不是固定的,而是以“a月的第b个星期c”的形 ...
- 安装配置SVN
官网下载地址,下载完之后如果想看到中文,可以下载语言包进行安装,安装之后TortoiseSVN -> Settings -> General -> Language选项中选择:中文( ...
- Haproxy 开启日志记录
CentOS 7上yum安装的Haproxy,默认没有记录日志.需要做一下配置才能记录日志.(不知道其他版本是否需要,已经忘记了)主要是用到了Haproxy,以前貌似没有这么麻烦,今天配置出了一些问题 ...
- 前端-JS-BOM和DOM
前戏 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我们还不能制作一些我们经常看到的网页的一些交互,我们需要继续学习BOM和DO ...
- 基于spring-boot的应用程序的单元+集成测试方案
目录 概述 概念解析 单元测试和集成测试 Mock和Stub 技术实现 单元测试 测试常规的bean 测试Controller 测试持久层 集成测试 从Controller开始测试 从中间层开始测试 ...
- CSUOJ 2031 Barareh on Fire
Description The Barareh village is on fire due to the attack of the virtual enemy. Several places ar ...
- eclipse 背景颜色
步骤阅读 3 本例使用的背景色是喜大普奔的豆沙绿,比较柔和 设置为:色调:85.饱和度:120.亮度:208 即可,据说长时间使用可以缓解眼疲劳哦. (吐槽:开什么玩笑,远离编程才能缓解眼疲劳好吗)