【Linux 线程】常用线程函数复习《二》
1、函数pthread_join
/*************************************************************************
> File Name: pthread_join1.c
> Summary: pthread_join函数的基本用法
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> struct thrd
{
int var;
char str[];
}; void *tfn(void *arg)
{
struct thrd *tval;
tval = malloc(sizeof(tval)); tval->var = ;
strcpy(tval->str, "hello xls");
return (void *)tval;
} int main()
{
pthread_t tid;
struct thrd *retval;
int ret = pthread_create(&tid, NULL, tfn, NULL);
if(ret != )
{
printf("create thread fail\n");
}
/*
函数pthread_join用来等待一个线程的结束,线程间同步的操作。头文件 : #include <pthread.h>
函数定义: int pthread_join(pthread_t thread, void **retval);
描述 :pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。
参数 :thread: 线程标识符,即线程ID,标识唯一线程。retval: 用户定义的指针,用来存储被等待线程的返回值。
返回值 : 0代表成功。 失败,返回的则是错误号。
*/
ret = pthread_join(tid, (void **)&retval);
printf("child thread exit and return values var = %d, str = %s\n", retval->var, retval->str);
pthread_exit(NULL);
return ;
}
运行结果:
child thread exit and return values var = , str = hello xls
2、函数pthread_cancel
/*************************************************************************
> File Name: pthread_cancel1.c
> Summary: 终止线程的函数 pthread_cancel()
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> void *tfn(void *arg)
{
while()
{
printf("thread :pid = %d, tid = %lu\n",getpid(), pthread_self());
sleep();
}
return NULL;
} int main()
{
pthread_t tid;
int ret = pthread_create(&tid, NULL, tfn, NULL);
if(ret != )
{
printf("pthread_create fail\n");
exit();
}
printf("main: pid = %d, tid = %lu\n",getpid(), pthread_self()); sleep(); /*
#include<pthread.h>
int pthread_cancel(pthread_t thread)
发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。
若是在整个程序退出时,要终止各个线程,应该在成功发送 CANCEL 指令后,使用 pthread_join 函数,等待指定的线程已经完全退出以后,再继续执行;否则,很容易产生 “段错误”。
*/
ret = pthread_cancel(tid); // 终止线程tid
if(ret != )
{
printf("pthread_cancel fail\n");
exit();
} while(); return ;
}
运行结果:
thread :pid = , tid =
main: pid = , tid =
thread :pid = , tid =
thread :pid = , tid =
thread :pid = , tid =
thread :pid = , tid =
(循环等待)
3、3种终止线程的方式:exit()、pthread_exit()、pthread_cancel
情形1:
/*************************************************************************
> File Name: pthread_cancel2.c
> Summary: 终止线程的3种方式:exit、pthread_exit()、 pthread_cancel()
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> void *tfn1(void *arg)
{
printf("thread 1 returning\n");
return (void *); // 线程函数中,这里的return (void *)111相当于 exit(111)
} void *tfn2(void *arg)
{
printf("thread 2 exiting\n");
pthread_exit((void *));
} void *tfn3(void *arg)
{
while()
{
printf("thread 3: I'm going to die in 3 seconds ...\n");
sleep();
/*pthread_testcanel(); // 自己添加取消点*/
}
return (void *);
}
int main()
{
pthread_t tid;
void *tret = NULL; pthread_create(&tid, NULL, tfn1, NULL);
pthread_join(tid, &tret);
printf("thread 1 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn2, NULL);
pthread_join(tid, &tret);
printf("thread 2 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn3, NULL);
sleep(); // 主线程休眠3秒
pthread_cancel(tid);
pthread_join(tid, &tret); // 主线程要回收子线程3,但是子线程3之前已经被cancel,tret所以返回值-1(表示失败)
printf("thread 3 exit code = %d\n\n", (int)tret); return ;
}
运行结果:
thread returning
thread exit code = thread exiting
thread exit code = thread : I'm going to die in 3 seconds ...
thread : I'm going to die in 3 seconds ...
thread : I'm going to die in 3 seconds ...
thread exit code = -
情形2:当pthread_cancel要终止的线程没有陷入内核的操作
/*************************************************************************
> File Name: pthread_cancel3.c
> Summary: 终止线程的3种方式:exit、pthread_exit()、 pthread_cancel() 当pthread_cancel要终止的线程没有陷入内核的操作
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> void *tfn1(void *arg)
{
printf("thread 1 returning\n");
return (void *); // 线程函数中,这里的return (void *)111相当于 exit(111)
} void *tfn2(void *arg)
{
printf("thread 2 exiting\n");
pthread_exit((void *));
} void *tfn3(void *arg)
{
29 while(1) // 终止的线程中没有陷入内核的操作(例如系统调用等)
{
//printf("thread 3: I'm going to die in 3 seconds ...\n");
//sleep(1);
/*pthread_testcanel(); // 自己添加取消点*/
}
return (void *);
}
int main()
{
pthread_t tid;
void *tret = NULL; pthread_create(&tid, NULL, tfn1, NULL);
pthread_join(tid, &tret);
printf("thread 1 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn2, NULL);
pthread_join(tid, &tret);
printf("thread 2 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn3, NULL);
sleep(); // 主线程休眠3秒
pthread_cancel(tid);
pthread_join(tid, &tret); // 主线程要回收子线程3,但是子线程3之前已经被cancel,tret所以返回值-1(表示失败)
printf("thread 3 exit code = %d\n\n", (int)tret); return ;
}
运行结果:
thread returning
thread exit code = thread exiting
thread exit code =
(光标在此while循环...)
情形3:解决当pthread_cancel要终止的线程没有陷入内核的操作---创建线程取消点
/*************************************************************************
> File Name: pthread_cancel4.c
> Summary: 终止线程的3种方式:exit、pthread_exit()、 pthread_cancel() 解决当pthread_cancel要终止的线程没有陷入内核的操作
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> void *tfn1(void *arg)
{
printf("thread 1 returning\n");
return (void *); // 线程函数中,这里的return (void *)111相当于 exit(111)
} void *tfn2(void *arg)
{
printf("thread 2 exiting\n");
pthread_exit((void *));
} void *tfn3(void *arg)
{
while() // 终止的线程中没有陷入内核的操作(例如系统调用等),可以添加函数pthread_testcanel()
{
//printf("thread 3: I'm going to die in 3 seconds ...\n");
//sleep(1);
pthread_testcancel(); // 自己添加取消点
}
return (void *);
}
int main()
{
pthread_t tid;
void *tret = NULL; pthread_create(&tid, NULL, tfn1, NULL);
pthread_join(tid, &tret);
printf("thread 1 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn2, NULL);
pthread_join(tid, &tret);
printf("thread 2 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn3, NULL);
sleep(); // 主线程休眠3秒
pthread_cancel(tid);
pthread_join(tid, &tret); // 主线程要回收子线程3,但是子线程3之前已经被cancel,tret所以返回值-1(表示失败)
printf("thread 3 exit code = %d\n\n", (int)tret); return ;
}
运行结果:
thread returning
thread exit code = thread exiting
thread exit code = thread exit code = -
【Linux 线程】常用线程函数复习《二》的更多相关文章
- php中的常用数组函数(三)(获取数组交集的函数们 array_intersect()、array_intersect_key()、array_intersect_assoc()、array_intersect_uassoc()、array_intersect_ukey())
这5个获取交集的函数 有 5个对应的获取差集的函数.我是链接. array_intersect($arr1, $arr2); //获得数组同键值的交集 array_intersect_key($arr ...
- Linux中常用的函数
1.devm_kzalloc() 函数 devm_kzalloc() 和kzalloc()一样都是内核内存分配函数,但是devm_kzalloc()是跟设备(device)有关的,当设备(device ...
- Linux 系统常用命令汇总(三) 用户和用户组管理
用户和用户组管理 命令 选项 注解 示例 useradd [选项] 用户名 新建用户 创建一个名为tester的用户,并指定他的UID为555,指定加入test群,指定其使用C-shell: use ...
- Linux最常用的基本操作复习
.ctrl + shift + = 放大终端字体 .ctrl + - 缩小终端字体 .ls 查看当前文件夹下的内容 .pwd 查看当前所在的文件夹 .cd 目录名 切换文件夹 .touch 如果文件不 ...
- Linux:结束线程的三种方式
一般情况下,线程终止后,其终止状态一直保留到其它线程调用pthread_join获取它的状态为止.但是线程也可以被置为detach状态,这样的线程一旦终止就立刻回收它占用的所有资源,而不保留终止状态. ...
- Linux可重入函数和线程安全的区别与联系(转)
*****可重入函数 函数被不同的控制流程调用,有可能在第一次调用还没返回时就再次进入该函数,这称为重入. 当程序运行到某一个函数的时候,可能因为硬件中断或者异常而使得在用户正在执行的代码暂时终端转而 ...
- Linux下通用线程池的创建与使用
线程池:简单地说,线程池 就是预先创建好一批线程,方便.快速地处理收到的业务.比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高. 在linux中,使用的 ...
- linux系统编程--线程
安装线程man page,命令:sudo apt-get install manpages-posix-dev 线程概念 什么是线程 LWP:light weight process 轻量级的进程,本 ...
- Linux进程间通信与线程间同步详解(全面详细)
引用:http://community.csdn.net/Expert/TopicView3.asp?id=4374496linux下进程间通信的几种主要手段简介: 1. 管道(Pipe)及有名管道( ...
- Linux平台下线程池的原理及实现
转自:http://blog.csdn.net/lmh12506/article/details/7753952 前段时间在github上开了个库,准备实现自己的线程池的,因为换工作的事,一直也没有实 ...
随机推荐
- redis如何清除所有的key
redis比memcache好的地方之一,如果memcache,恐怕就得关掉重启了. 1 使用cli FLUSHDB 清除一个数据库,FLUSHALL清除整个redis数据. 2 使用shell re ...
- 自己写一个spring boot starter
https://blog.csdn.net/liuchuanhong1/article/details/55057135
- [C语言]变量VS常量
-------------------------------------------------------------------------------------------- 1. 固定不变 ...
- Android DevArt4:IntentFilter学习及深入~问题描述:在不指定具体action前提下,如果有两个以上的Activity,具有完全相同的intent-filter,项目同步是否会出现异常?程序运行是否会崩溃?
概述:GitHub IntentFilter意图过滤器,三种匹配规则:action.category.data 重点:过滤规则中必须设置 '<category android:name=&quo ...
- Swift自定义UINavigationController(背景颜色、背景图片、返回按钮设置、字体大小等)
1.0 自定义UINavigationController时,背景图片.颜色等只需要设置一次,所以我们可以重写 initializa 这个方法来实现我们想要的效果 override class ...
- C# 反射获取所有视图
原地址:忘了 controller 的 action 加上属性 [System.ComponentModel.Description("菜单列表")] 且 返回值为 Syste ...
- C++读取txt和保存到txt
哇,今天又重新用C++来写了一些代码发现自己竟然在类的使用和文件读取和保存上面特别头疼,于是,各种问度娘+各种翻看之前的代码.不禁感叹,自己的代码还是写的太少了,对这些一点都不熟悉.于是,今晚!一定! ...
- ADO.Net创建数据模型和数据访问类及泛型集合
数据模型和数据访问类:数据模型: 使用面向对象中的封装特性,将数据表中的行数据组成一个同样结构的对象,来单独使用: 数据访问类: 将某一个表的全部增删改查操作的方法写进去,方便统一管理和调用: 数据模 ...
- php导出excel不知道列数 php26进制函数
function num2Letter($num) { $num = intval($num); if ($num <= 0) return false; $letterArr = array( ...
- eclipse老运行上一个程序之原因总结
运行eclipse有的时候不运行刚写的类,老是运行别的以前的类,删除了以前的类就啥都不运行.找了好久的原因,最后发现,刚写的类没有main()或者有误.这和java的特点有关,程序的运行总是main( ...