线程与进程关键字对比

创建新流 fork/pthread_create

退出控制流 exit/pthread_exit

获取退出状态 waitpid/pthread_join

在退出时的清理工作 atexit/pthread_cleanup_push

非正常退出 abort/pthread_cancel

创建线程

int pthread_create(线程ID返回值, 线程属性, 任务地址, 任务附加参数)

获取线程ID: pthread_t pthread_self(void)

判断是否同一线程: int pthread_equal(pthread_t tid1, pthread_t tid2)

线程终止

线程退出方式: pthread_exit; 线程正常执行完毕返回; 被同一进程中的其它线程取消

错误退出方式: 调用exit, _exit, _Exit都会使整个进程退出

获取返回值: pthread_join

线程清理

pthread_cleanup_push: 添加一个清理函数, 如果意外退出可以确保资源释放

pthread_cleanup_pop(0): 取消清理函数, 比如主动清理完成时便可以调用pop来取消push的操作

以下三种情况会触发push操作:

  • 调用pthread_exit退出(调用return不会触发)
  • 响应pthread_cancel请求
  • pthread_cleanup_pop(int), int参数为非零时

线程同步

1.互斥量

2.读写锁

3.条件变量

例子

1.创建和退出线程

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h> void *
thr_fn1(void *arg){
printf("thread 1 returning \n");
return((void *)1);
} void *
thr_fn2(void *arg){
printf("thread 2 exiting\n");
pthread_exit((void *)2);
} int main(){
int err;
pthread_t tid1,tid2;
void *tret; err=pthread_create(&tid1,NULL,thr_fn1,NULL);
if(err != 0){
perror("pthread_create error");
return -1;
}
err=pthread_create(&tid2,NULL,thr_fn2,NULL);
if(err != 0){
perror("pthread_create error");
return -1;
} err=pthread_join(tid1,&tret);
if(err != 0){
perror("pthread_join error");
return -1;
}
printf("thread 1 exit code %d\n",(int)tret);
err=pthread_join(tid2,&tret);
if(err != 0){
perror("pthread_join error");
return -1;
}
printf("thread 2 exit code %d\n",(int)tret);
return 0;
}

2.清理函数

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h> void cleanup(void *arg){
printf("in cleanup : %s\n",arg);
} void *
thr_fn1(void *arg){
puts("thread start");
pthread_cleanup_push(cleanup,"the first time");
pthread_cleanup_push(cleanup,"the second time");
if(1==(int)arg)
return((void*)1);
else if(2==(int)arg)
pthread_exit((void*)2);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
return ((void *)0);
} int main(){
int err;
pthread_t tid1;
void *tret; //pthread_create第四个参数,
//0时会执行pop取消清理函数, 1时以return方式退出不触发清理函数,2时以pthread_exit方式退出触发清理函数
err=pthread_create(&tid1,NULL,thr_fn1,(void *)1);
if(err != 0){
perror("pthread_create error");
return -1;
} err=pthread_join(tid1,&tret);
if(err != 0){
perror("pthread_join error");
return -1;
}
printf("thread 1 exit code %d\n",(int)tret);
return 0;
}

3.互斥量

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h> struct people{
char name[10];
int age;
int count;
pthread_mutex_t lock;
}; struct people * init(){
struct people *man;
if((man=malloc(sizeof(struct people))) != NULL){
man->count=1;
if(pthread_mutex_init(&man->lock,NULL) != 0){
free(man);
return NULL;
}
strcpy(man->name,"wahaha");
man->age=20;
}
return man;
} void add_count(struct people *man){
pthread_mutex_lock(&man->lock);
puts("----in add_count----");
printf("now count=%d\n",++man->count);
puts("----out add_count----");
pthread_mutex_unlock(&man->lock);
} void del_count(struct people *man){
pthread_mutex_lock(&man->lock);
if(--man->count == 0){
pthread_mutex_unlock(&man->lock);
pthread_mutex_destroy(&man->lock);
puts("last count to del");
free(man);
}else{
pthread_mutex_unlock(&man->lock);
}
} void * thr_fn(void *arg){
add_count(arg);
sleep(1);
del_count(arg);
} int main(){
struct people *man;
man=init();
if(man == NULL){
perror("man init error");
return -1;
} int err;
pthread_t tid1,tid2; err=pthread_create(&tid1,NULL,thr_fn,man);
if(err != 0){
perror("pthread_create error");
return -1;
}
err=pthread_create(&tid2,NULL,thr_fn,man);
if(err != 0){
perror("pthread_create error");
return -1;
} err=pthread_join(tid1,NULL);
if(err != 0){
perror("pthread_join error");
return -1;
}
err=pthread_join(tid2,NULL);
if(err != 0){
perror("pthread_join error");
return -1;
} del_count(man);
return 0;
}

linux 线程笔记的更多相关文章

  1. linux线程笔记1之创建线程

    1 线程与进程的对比 这里有一个笔记详细的阐述 http://blog.csdn.net/laviolette/article/details/51506953 2 创建线程函数 int pthrea ...

  2. Dubbo入门到精通学习笔记(十一):Dubbo服务启动依赖检查、Dubbo负载均衡策略、Dubbo线程模型(结合Linux线程数限制配置的实战分享)

    文章目录 Dubbo服务启动依赖检查 Dubbo负载均衡策略 Dubbo线程模型(结合Linux线程数限制配置的实战分享) 实战经验分享( ** 属用性能调优**): Dubbo服务启动依赖检查 Du ...

  3. Linux线程互斥学习笔记--详细分析

    一.互斥锁 为啥要有互斥? 多个进程/线程执行的先后顺序不确定,何时切出CPU也不确定. 多个进程/线程访问变量的动作往往不是原子的. 1. 操作步骤 (1)创建锁 // 创建互斥锁mutex pth ...

  4. linux线程的实现

    首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个分身可以处理一件特定事情.这在处理异步事件如异步IO时特别有用.内核线程的使用是廉价的,唯一使用 ...

  5. 跟着鸟哥学Linux系列笔记3-第11章BASH学习

    跟着鸟哥学Linux系列笔记0-扫盲之概念 跟着鸟哥学Linux系列笔记0-如何解决问题 跟着鸟哥学Linux系列笔记1 跟着鸟哥学Linux系列笔记2-第10章VIM学习 认识与学习bash 1. ...

  6. linux线程的实现【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3620204.html 首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个 ...

  7. Linux 读书笔记 二

    一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码shiyanlou 若不小心登出后,直接刷新页面即可 2. 环境使用 完成实验后可以点击桌面上方的“实验截图”保存并分 ...

  8. 【转载】linux内核笔记之进程地址空间

    原文:linux内核笔记之进程地址空间 进程的地址空间由允许进程使用的全部线性地址组成,在32位系统中为0~3GB,每个进程看到的线性地址集合是不同的. 内核通过线性区的资源(数据结构)来表示线性地址 ...

  9. # linux读书笔记(3章)

    linux读书笔记(3章) 标签(空格分隔): 20135328陈都 第三章 进程管理 3.1 进程 进程就是处于执行期的程序(目标码存放在某种存储介质上).但进程并不仅仅局限于一段可执行程序代码( ...

随机推荐

  1. iphone 手机屏幕和UIView和UIWindowde 的主要的区别

    在iPhone5之前的iphone1,2,3,3s,4,4s都是320x480 iPhone5和5s的屏幕是320x568 iphone6的屏幕是375x667 iPhone6Plus的414x736 ...

  2. Oracle基础 exp/imp命令

    一.导出方式: 使用exp/imp方式导出数据分为四种方式: 1.表方式导出:一个或多个指定的表,包括表的定义.表数据.表的所有者授权.表索引.表约束,以及创建在该表上的触发器.也可以只导出结构,不导 ...

  3. 剑指Offer46 求1+2+...+n

    /************************************************************************* > File Name: 46_Accumu ...

  4. Macbook之设置Finder显示文件完整路径

    终端里输入:defaults write com.apple.finder _FXShowPosixPathInTitle -bool TRUE;killall Finder 回复输入:default ...

  5. NodeJS学习之异步编程

    NodeJS -- 异步编程 NodeJS最大的卖点--事件机制和异步IO,对开发者并不透明 代码设计模式 异步编程有很多特有的代码设计模式,为了实现同样的功能,使用同步方式和异步方式编写代码会有很大 ...

  6. 提高HTML5 Canvas性能的技巧

    详细内容请点击 一:使用缓存技术实现预绘制,减少重复绘制Canvs内容 很多时候我们在Canvas上绘制与更新,总是会保留一些不变的内容,对于这些内容 应该预先绘制缓存,而不是每次刷新. 直接绘制代码 ...

  7. 二维码zxing源码分析(一)camera部分

    首先,我们先把zxing的源代码给下载下来,这个网上有很多,我下载的是2.3的,不得不说这个谷歌提供的包包含的功能还是很全面的.     我把下载的包解压后,找到android文件夹,导入到ecpli ...

  8. 让项目管理理论“落地”——读《IT项目经理成长手记》有感

    最近利用业余时间阅读了一本好书--<IT项目经理成长手记>(潘东.韩秋泉著).本书的两位作者是神州数码(中国本土最大的整合IT服务提供商)的高管,在书中他们介绍了神州数码在IT项目管理领域 ...

  9. 简单的表单验证插件(Jquery)

    在做web开发的时候经常遇到表单验证问题,表单验证一般有客户端验证和服务器端验证,这个验证插件仅仅能满足我的项目中的基本需求的. Validate_Tools.js function Validate ...

  10. Java类加载的时机_4种主动引用会触犯类加载+剩下的被动引用不会触发类的加载

    转载自:http://chenzhou123520.iteye.com/blog/1597597 Java虚拟机规范没有强制性约束在什么时候开始类加载过程,但是对于初始化阶段,虚拟机规范则严格规定了有 ...