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. too many connections 解决方法

    最近写javaee项目的时候,mysql报了too many connections的错误,百度的内容有一些有问题,所以我重新写一下我的解决方法. mysql -u root -p 回车输入密码进入m ...

  2. English-英语学习杂志及资料

    [英文原版杂志] >>经济学人 英文原版PDF+双语版+文本音频 超全下载!http://bbs.zhan.com/thread-8443-1-1.html?sid=2004 >&g ...

  3. HBuilder开发APP自动登录时跳过"登录页面"

    刚接触开发公司APP项目,用HBuilder开发工具. manifest.json中的入口页面就是"登录页面",现在获取到自动登录状态是true,但是真机联调时"登录页面 ...

  4. select as table

    select order_time, max(sum_price) from (SELECT order, sum(price) as sum_price FROM orders group by o ...

  5. CSS DISPLAY AND POSITIONING

    CSS DISPLAY AND POSITIONING Review: Layout Great job! In this lesson, you learned how to control the ...

  6. java后端实习生面试题目

    1.编程题:java从10000到99999找到AABB类型 public class Test1 { public static void main(String[] args) { String ...

  7. Zabbix 3.0 LTS安装配置

    关于Zabbix监控项类型的官网介绍: https://www.zabbix.com/documentation/3.4/zh/manual/config/items/itemtypes zabbix ...

  8. 关于linux 内存碎片指数

    linux针对每一个node的每个zone的每个order,都有一个碎片指数来描述当前的碎片程度,也就是 extfrag_index 参数: extfrag_index这个要展示出来,需要内核编译了两 ...

  9. ReactiveX 学习笔记(0)学习资源

    ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...

  10. bcrelay广播包转发器

    https://www.mankier.com/8/bcrelay PPTP原是基于PPP的三层通信协议,加入bcrelay后可以将二层的广播包转发到PPTP的client端 在openwrt中实现的 ...