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 线程】常用线程函数复习《二》的更多相关文章

  1. 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 ...

  2. Linux中常用的函数

    1.devm_kzalloc() 函数 devm_kzalloc() 和kzalloc()一样都是内核内存分配函数,但是devm_kzalloc()是跟设备(device)有关的,当设备(device ...

  3. Linux 系统常用命令汇总(三) 用户和用户组管理

    用户和用户组管理 命令 选项 注解 示例 useradd [选项] 用户名 新建用户 创建一个名为tester的用户,并指定他的UID为555,指定加入test群,指定其使用C-shell:  use ...

  4. Linux最常用的基本操作复习

    .ctrl + shift + = 放大终端字体 .ctrl + - 缩小终端字体 .ls 查看当前文件夹下的内容 .pwd 查看当前所在的文件夹 .cd 目录名 切换文件夹 .touch 如果文件不 ...

  5. Linux:结束线程的三种方式

    一般情况下,线程终止后,其终止状态一直保留到其它线程调用pthread_join获取它的状态为止.但是线程也可以被置为detach状态,这样的线程一旦终止就立刻回收它占用的所有资源,而不保留终止状态. ...

  6. Linux可重入函数和线程安全的区别与联系(转)

    *****可重入函数 函数被不同的控制流程调用,有可能在第一次调用还没返回时就再次进入该函数,这称为重入. 当程序运行到某一个函数的时候,可能因为硬件中断或者异常而使得在用户正在执行的代码暂时终端转而 ...

  7. Linux下通用线程池的创建与使用

    线程池:简单地说,线程池 就是预先创建好一批线程,方便.快速地处理收到的业务.比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高. 在linux中,使用的 ...

  8. linux系统编程--线程

    安装线程man page,命令:sudo apt-get install manpages-posix-dev 线程概念 什么是线程 LWP:light weight process 轻量级的进程,本 ...

  9. Linux进程间通信与线程间同步详解(全面详细)

    引用:http://community.csdn.net/Expert/TopicView3.asp?id=4374496linux下进程间通信的几种主要手段简介: 1. 管道(Pipe)及有名管道( ...

  10. Linux平台下线程池的原理及实现

    转自:http://blog.csdn.net/lmh12506/article/details/7753952 前段时间在github上开了个库,准备实现自己的线程池的,因为换工作的事,一直也没有实 ...

随机推荐

  1. shell脚本运行springboot项目jar包

    #!/bin/bash APP_NAME=AutomationGuide-0.0.1-SNAPSHOT.jar #使用说明,用来提示输入参数 usage() { echo "please e ...

  2. Oracle 学习总结 - 问题诊断

    搜集常用诊断sql https://blog.csdn.net/yangshangwei/article/details/52449489 lock相关: 1. 查看lock, 打开两个事物,事物1更 ...

  3. html 自定义属性的获取和应用

    在html 中,我们可以给元素设置自定义属性,格式:  data-属性="属性值",可以设置一个,也可以设置多个 1.获取元素属性的常规方法:直接获取元素,然后使用getAttri ...

  4. js总结001

    JSTL 表达式与 EL 语言      http://leon906998248.iteye.com/blog/1502569 2   jquery中$each()方法的使用指南     http: ...

  5. PostgresQL 中有没有rownum这样的,显示结果集的序号

    select * from (select row_number() over() as rownum,tablename from pg_tables) t where rownum<10;

  6. Haskell语言学习笔记(83)Pipes

    安装 pipes $ cabal install pipes Installed pipes-4.3.9 Prelude> import Pipes Prelude Pipes> impo ...

  7. 21.struts-Action配置.md

    目录 1.Action开发方式 2.通配符 访问地址 [toc] 3.常量 后缀 指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法和freema ...

  8. JSTL标签不起作用的解决办法

    JSP页面中的EL标签直接成字符串输出(如:${user.id}),说明el标签没有被识别,造成的原因有: 1.jdk+jstl的组合不匹配 2.web.xml版本不匹配 但我们解决以上这个问题时,先 ...

  9. 吴裕雄 32-MySQL 导入数据

    1.mysql 命令导入使用 mysql 命令导入语法格式为:mysql -u用户名 -p密码 < 要导入的数据库数据(runoob.sql)实例:# mysql -uroot -p123456 ...

  10. ABAP 常用函数

    函数名 描述 SD_VBAP_READ_WITH_VBELN 根据销售订单读取表vbap中的信息EDIT_LINES 把READ_TEXT返回的LINES中的行按照TDFORMAT=“*”重新组织VI ...