Linux高级编程--08.线程概述
线程
有的时候,我们需要在一个基础中同时运行多个控制流程。例如:一个图形界面的下载软件,在处理下载任务的同时,还必须响应界面的对任务的停止,删除等控制操作。这个时候就需要用到线程来实现并发操作。
和信号处理函数的控制在处理完信号之后就结束不同的是,多线程的控制流程可以长期并存,操作系统会在各线程之间调度和切换,就像在多个进程之间调度和切换一样,但创建线程开销要比进程小得多。因此,线程往往也被称作轻量级的进程。
由于同一进程的多个线程共享同一地址空间,数据段是共享的,如果定义一个全局变量,在各线程中都可以访问到。但有,些资源依然是每个线程各有一份的:
- 线程id
- 上下文,包括各种寄存器的值、程序计数器和栈指针
- 栈空间
- errno变量
- 信号屏蔽字
- 调度优先级
我们一般用到的是由POSIX标准定义的线程库函数,称为POSIX thread或者pthread。在Linux上线程函数位于libpthread共享库中,因此在编译时要加上-lpthread选项。
创建线程
在POSIX库中,创建线程是通过函数实现的,它的声明如下:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
它有四个参数,
- 第一个参数thread为创建后的线程标识符的指针。
- 第二个参数attr为线程属性,可选为PTHREAD_CREATE_DETACHED(分离线程)和 PTHREAD _CREATE_JOINABLE(非分离线程),一般是直接用NULL。
- 第三个参数start_routine为线程的运行函数
- 第四个参数arg为线程运行函数的参数
创建成功时,返回0,失败是返回错误码。这个和其它的系统函数失败返回-1,由errno返回错误码不大一样。
等待线程结束
有的时候,我们需要等待线程结束,此时才能继续执行后面的事情。拿前面的例子来说,如果不等待线程结束,则主线程(main函数)会直接往下执行导致程序退出,线程函数都无法得到执行。
pthread库中等待线程结束的函数是pthread_join,它的声明如下:
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
它有两个参数,
- 第一个参数是线程标识符,
- 第二个参数是个出参,用户获取线程函数的返回值。
终止线程
终止线程的方法一般来说有如下几种:
- 线程函数调用return终止自己
- 线程调用pthread_exit终止自己
- 线程可以调用pthread_cancel终止同一进程中的其它线程
其中,方法1和方法2都是通过结束线程函数来实现主动退出的,它们是比较常用的方法。方法3则是一种强制终止的做法,这个方法一个问题就是导致对象的析构函数可能无法执行,会出现资源泄漏,并不推荐用这种方法。
一个简单的示例
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void* thr_fn(void *arg)
{
pid_t pid = getpid();
pthread_t tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n", arg, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid);
return NULL;
}
int main(void)
{
pthread_t ntid = {0};
int err = pthread_create(&ntid, NULL, thr_fn, (void*)"new thread: ");
if (err != 0)
{
fprintf(stderr, "can't create thread: %s\n", strerror(err));
exit(1);
}
void *tret;
pthread_join(ntid, &tret);
printf("thread exited\n");
return 0;
}
编译程序
gcc thread.c -o thread -lpthread
运行结果
new thread: pid 21231 tid 1082132800 (0x40800940)
thread exited
Linux高级编程--08.线程概述的更多相关文章
- Linux高级编程--09.线程互斥与同步
多个线程同时访问共享数据时可能会冲突,比如两个线程都要把某个全局变量增加1,这个操作在某平台需要三条指令完成: 从内存读变量值到寄存器 寄存器的值加1 将寄存器的值写回内存 假设两个线程在多处理器平台 ...
- Linux高级编程--06.进程概述
进程控制块 在Linux中,每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,它通常包含如下信息: 进程id.系统中每个进程有唯一的id,在C语言中用pid_t类型表示,其实就是一个非 ...
- linux高级编程基础系列:线程间通信
linux高级编程基础系列:线程间通信 转载:原文地址http://blog.163.com/jimking_2010/blog/static/1716015352013102510748824/ 线 ...
- 【UNIX环境高级编程】线程同步
当多个线程共享相同的内存时,需要确保每个线程看到一致的数据视图.如果每个线程使用的变量都是其他线程不会读取和修改的,那么就不存在一致性问题.同样,如果变量是只读的也不会有一致性问题.但是,当一个线程可 ...
- Linux高级编程--04.GDB调试程序(入门概述)
GDB概述 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试 ...
- linux高级编程
系统调用 01.什么是系统调用? 02.Linux系统调用之I/O操作(文件操作) 03.文件描述符的复制:dup(), dup2() 多进程实现多任务 04.进程的介绍 05.Linux可执行文件结 ...
- linux高级编程补充知识
F: 计算机系统结构: ------------------------------- 应用程序 ----------------- | 库函数 -------------------------- ...
- Linux高级编程--10.Socket编程
Linux下的Socket编程大体上包括Tcp Socket.Udp Socket即Raw Socket这三种,其中TCP和UDP方式的Socket编程用于编写应用层的socket程序,是我们用得比较 ...
- Linux高级编程--05.文件读写
缓冲I/O和非缓冲I/O 文件读写主要牵涉到了如下五个操作:打开.关闭.读.写.定位.在Linux系统中,提供了两套API, 一套是C标准API:fopen.fclose.fread.fwrite.f ...
随机推荐
- 语音直播是否真能让国内网红向“Creator”转变?
2016年,“直播”.“网红”成为了互联网领域最热门的关键词,一时间整个国内市场涌现出了数百家直播平台,而一些视频网站.新闻客户端.社交平台.电商平台等也纷纷推出直播功能.不仅仅只是创业者们像发了疯似 ...
- iOS学习笔记-精华整理
iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...
- Eclipse连接到My sql数据库之前操作
Eclipse连接到My sql数据库之前操作 1:首先是安装My sql数据库(为了减少你的麻烦,按照下面的连接,下载即可)百度云链接:http://pan.baidu.com/s/1mitWmbm ...
- python数据持久存储:pickle模块的使用
python的pickle模块实现了基本的数据序列和反序列化.通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储:通过pickle模块的反序列化操作,我们能够从文件 ...
- Android高仿微信图片选择功能的PhotoPicker
类似于微信修改头像的功能基本上每个app都会有,以前公司开发的项目就有修改头像的功能,但是用的Android系统自带的图片选择器.用Android系统的图片选择器有个好处就是稳定,不会有什么问题.但也 ...
- java 发送带Basic Auth认证的http post请求
构造http header private static final String URL = "url"; private static final String APP_KEY ...
- Expender Header 与 Content互斥展示
Expender 在展开时,Header 不展示:不展开时,展示 Header <Expander dxlc:DockLayoutControl.Dock="Top" IsE ...
- 机器学习基石--学习笔记01--linear hard SVM
背景 支持向量机(SVM)背后的数学知识比较复杂,之前尝试过在网上搜索一些资料自学,但是效果不佳.所以,在我的数据挖掘工具箱中,一直不会使用SVM这个利器.最近,台大林轩田老师在Coursera上的机 ...
- C#接口的使用场合,接口应用
当一个项目不断的扩大的时候,会面临的问题是不断的有以下情况: 1.以前编写程序的人离职了,新来的程序员看不懂以前的程序,或者觉得以前的程序部够好,但又不希望删除: 2.当实现第三方接口时,如:读写IC ...
- Multiple Contexts have a path of "/xxxx"问题解决
转自:http://blog.csdn.net/ivanzhangqf/article/details/50326533 之前因为ecplise项目保存更新时一直显示等待后台操作完成,以至于一直卡住无 ...