1、pthread_create以及pthread_self函数

 /*************************************************************************
> File Name: pthread1.c
> Summary: 两个函数的使用:pthread_create() 以及函数 pthread_self()
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include<stdio.h>
#include<stdlib.h>
#include<pthread.h> void *callBack()
{
// pthread_self():用来获得线程id。返回值为线程id,没有参数。
printf("pthread_self return value = %lu", pthread_self());
return NULL;
} int main()
{
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 NULL
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int ret = pthread_create(&pid,NULL,callBack,NULL);
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
//阻塞主线程一会
sleep();
return ;
}

运行结果:

pthread_self return value = 

2、循环创建多个子线程

第一种情况:

 /*************************************************************************
> File Name: pthread2.c
> Summary: pthread_create() 循环创建多个线程
> 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 *callBack(void *arg)
{
int i = (int)arg;
sleep(i);
// pthread_self():用来获得线程id。返回值为线程id,没有参数。
printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu\n", i+, getpid(), pthread_self());
return NULL;
} int main()
{
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 null
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int i;
for(i = ; i<; i++)
{
int ret = pthread_create(&pid,NULL,callBack, (void *)i);
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
} //阻塞主线程一会
sleep(i);
printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", getpid(), pthread_self());
return ;
}

运行结果:

 i am  th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am main thread,getpid() = ,pthread_self return value =

第二种情况:

 /*************************************************************************
> File Name: pthread3.c
> Summary: pthread_create() 循环创建多个线程(第二种情况)
> 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 *callBack(void *arg)
//{
// int i = (int)arg;
void *callBack(void *arg)
{
int i = *((int *)arg);
sleep(i);
// pthread_self():用来获得线程id。返回值为线程id,没有参数。
printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu\n", i+, getpid(), pthread_self());
return NULL;
} int main()
{
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 null
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int i;
for(i = ; i<; i++)
{
//int ret = pthread_create(&pid,NULL,callBack, (void *)i);
int ret = pthread_create(&pid,NULL,callBack, (void *)&i); //注意这里如果取地址,主线程的i不断变化,所以取到的i值出现混乱
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
} //阻塞主线程一会
sleep(i);
printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", getpid(), pthread_self());
return ;
}

运行结果:

 i am  th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am main thread,getpid() = ,pthread_self return value =

3、线程间全局变量共享

 /*************************************************************************
> File Name: pthread4.c
> Summary: 线程间全局变量共享 验证
> 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> // 定义全局变量
int var = ;
void *callBack()
{
var = ;
printf("child thread running now var = %d\n", var);
return NULL;
} int main()
{
printf("before child thread create var = %d\n", var);
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 null
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int ret = pthread_create(&pid,NULL,callBack, NULL);
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
//阻塞主线程一会
sleep();
printf("after child thread over now var = %d\n", var);
return ;
}

运行结果:

 before child thread create var =
child thread running now var =
after child thread over now var =

4、函数pthread_exit()

情形一:

 /*************************************************************************
> File Name: pthread5.c
> Summary: pthread_exit函数之 使用exit函数退出线程
> 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 *callBack(void *arg)
{
int i = (int)arg;
sleep(i);
19 if(i == 2){
20 exit(0);
21 }

// pthread_self():用来获得线程id。返回值为线程id,没有参数。
printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu\n", i+, getpid(), pthread_self());
return NULL;
} int main()
{
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 null
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int i;
for(i = ; i<; i++)
{
int ret = pthread_create(&pid,NULL,callBack, (void *)i);
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
} //阻塞主线程一会
sleep(i);
printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", getpid(), pthread_self());
return ;
}

运行结果:

i am  th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =

使用exit函数退出线程:exit()进程退出,如果在线程函数中调用exit,那改线程的进程也就挂了,会导致该线程所在进程的其他线程也挂掉,比较严重。

情形2-1:使用return 退出线程

 /*************************************************************************
> File Name: pthread6.c
> Summary: pthread_exit函数之 使用return 退出线程
> 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 *callBack(void *arg)
{
int i = (int)arg;
sleep(i);
19 if(i == 2){
20 return NULL;
21 }

// pthread_self():用来获得线程id。返回值为线程id,没有参数。
printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu\n", i+, getpid(), pthread_self());
return NULL;
} int main()
{
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 null
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int i;
for(i = ; i<; i++)
{
int ret = pthread_create(&pid,NULL,callBack, (void *)i);
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
} //阻塞主线程一会
sleep(i);
printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", getpid(), pthread_self());
return ;
}

运行结果:(正常)

 i am  th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am main thread,getpid() = ,pthread_self return value =

情形2-2:使用return 退出线程(嵌套)

 /*************************************************************************
> File Name: pthread7.c
> Summary: pthread_exit函数之 使用return 退出线程(嵌套)
> 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> 15 void *fun(){
16 return NULL;
17 }

void *callBack(void *arg)
{
int i = (int)arg;
sleep(i);
23 if(i == 2){
24 fun();
25 }

// pthread_self():用来获得线程id。返回值为线程id,没有参数。
printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu\n", i+, getpid(), pthread_self());
return NULL;
} int main()
{
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 null
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int i;
for(i = ; i<; i++)
{
int ret = pthread_create(&pid,NULL,callBack, (void *)i);
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
} //阻塞主线程一会
sleep(i);
printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", getpid(), pthread_self());
return ;
}

运行结果:(不正常)

i am  th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am main thread,getpid() = ,pthread_self return value =

结论:return是函数返回,不一定是线程函数哦(情形2-2)! 只有线程函数(情形2-1)return,线程才会退出。

情形3-1:使用pthread_exit函数退出

 /*************************************************************************
> File Name: pthread8.c
> Summary: pthread_exit函数 情形1
> 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 *callBack(void *arg)
{
int i = (int)arg;
sleep(i);
19 if(i == 2){
20 // 函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。函数无返回值,参数为传出参数。
21 pthread_exit(NULL);
22 }

// pthread_self():用来获得线程id。返回值为线程id,没有参数。
printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu\n", i+, getpid(), pthread_self());
return NULL;
} int main()
{
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 null
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int i;
for(i = ; i<; i++)
{
int ret = pthread_create(&pid,NULL,callBack, (void *)i);
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
} //阻塞主线程一会
sleep(i);
printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", getpid(), pthread_self());
return ;
}

运行结果:(正常)

i am  th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am main thread,getpid() = ,pthread_self return value =

情形3-2:使用pthread_exit函数退出(嵌套)

 /*************************************************************************
> File Name: pthread9.c
> Summary: pthread_exit函数 情形2 (嵌套)
> 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> 15 void *fun()
16 {
17 pthread_exit(NULL);
18 }

void *callBack(void *arg)
{
int i = (int)arg;
sleep(i);
24 if(i == 2){
25 // 函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。函数无返回值,参数为传出参数。
26 //pthread_exit(NULL);
27 fun();
28 }

// pthread_self():用来获得线程id。返回值为线程id,没有参数。
printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu\n", i+, getpid(), pthread_self());
return NULL;
} int main()
{
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 null
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int i;
for(i = ; i<; i++)
{
int ret = pthread_create(&pid,NULL,callBack, (void *)i);
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
} //阻塞主线程一会
sleep(i);
printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", getpid(), pthread_self());
return ;
}

运行结果:(正常)

i am  th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am main thread,getpid() = ,pthread_self return value =

pthread_exit()用于线程退出,可以指定返回值,以便其他线程通过pthread_join()函数获取该线程的返回值。

情形4:主函数中使用pthread_exit替代sleep:

 /*************************************************************************
> File Name: pthread10.c
> Summary: pthread_create() 循环创建多个线程 主函数中使用pthread_exit替代sleep
> 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 *callBack(void *arg)
{
int i = (int)arg;
sleep(i);
// pthread_self():用来获得线程id。返回值为线程id,没有参数。
printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu\n", i+, getpid(), pthread_self());
return NULL;
} int main()
{
pthread_t pid;
/*
pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid
参数2:属性 null
参数3:回调函数的函数指针。
参数4:回调函数的参数列表。没有的话传NULL
*/
int i;
for(i = ; i<; i++)
{
int ret = pthread_create(&pid,NULL,callBack, (void *)i);
if(ret != )
{
printf("pthread_create fail\n");
exit(-);
}
} //阻塞主线程一会
//sleep(i);
printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", getpid(), pthread_self());
// 这里使用pthread_exit替换sleep()
pthread_exit(NULL);
return ; // 主函数中使用return退出,相当于使用exit函数
}

运行结果:

i am main thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =
i am th thread,getpid() = ,pthread_self return value =

【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. Mysql 定时任务事件

    参考文献:https://blog.csdn.net/dream_ll/article/details/73499750

  2. mobile-net v2 学习记录。我是菜鸡!

    声明:只是自己写博客总结下,不保证正确性,我的理解很可能是错的.. 首先,mobile net V1的主要特点是: 1.深度可分离卷积.用depth-wise convolution来分层过滤特征,再 ...

  3. LeetCode OJ 215. Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  4. 简单实现"回车!=提交"(去除表单的回车即提交)

    -------------------------------------------------------------------------------------------------- 实 ...

  5. python 多重继承 深度优先还是广度优先

    我们常说,python2 是深度优先,python3 是广度优先, 其实具体来说是 python2.2 及其以前是深度优先 python2.3及其以后就是广度优先了 python官网 讲解1 以及su ...

  6. Hibernate 再接触 树状结构设计以及学生课程成绩表的设计

    1 树状结构的设计 package com.bjsxt.hibernate; import java.util.HashSet; import java.util.Set; import javax. ...

  7. servlet(1)request常用方法

    HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息. req ...

  8. 通过DOS命令批量重命名文件

    以下为提供的两种方法:遍历当前目录下的所有文件名以.avi结尾的文件,然后权限规则进行修改(规则含义请自行查找资料).第一种方法有缺陷,更改完所有的文件名后,会多改一次.请斟酌使用.第二种方法解决了第 ...

  9. 零基础用Docker部署微服务

    1. docker架构 这里的Client和DOCKER_HOST(docker server)都是在本地的,docker仓库Registry是在远程的: Client的docker命令通过Docke ...

  10. DM 9000网卡驱动移植

    1. 由于内核已经带有DM9000 网卡的驱动,所以主要移植工作是在板文件中添加 platform_device 结构,并加入 ok6410_devices[] __initdata 数组. 代码如下 ...