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. day28-面相对象的特殊成员、内置函数

    1. isinstance与issubclass 1.1.isinstance(obj,cls) 检查obj是否是类cls的对象,或者是类cls的子类的对象 class A: pass class B ...

  2. css-图片垂直居中

    1. img { vertical-align: middle; }   2. <body> <div> <img src="1.jpg" alt=& ...

  3. 尚硅谷springboot学习9-配置文件值注入

    首先让我想到的是spring的依赖注入,这里我们可以将yaml或者properties配置文件中的值注入到java bean中 配置文件 person: lastName: hello age: 18 ...

  4. 尚硅谷redis学习7-持久化AOF

    AOF比RDB优点在于数据的实时性高,经过设置后最多只会损失一秒钟的数据,而RDB最多可能损失上次备份到此次DOWM机间的数据 原理 配置文件 设置同步频率 重启redis,测试,可以看到数据在关机重 ...

  5. cxgrid中回车键光标移到下列

    OptionsBehavior.GoToNextCellOnEnter:=True; 更完善的回车 可以在焦点到了最后一列再回车时有下一行则移到下一行的第一列,没有下一行则新增记录并移到第一列 pro ...

  6. Nginx反向代理时tomcat日志获取真实IP

    对于nginx+tomcat这种架构,如果后端tomcat配置保持默认,那么tomcat的访问日志里,记录的就是前端nginx的IP地址,而不是真实的访问IP.因此,需要对nginx.tomcat做如 ...

  7. Visual Studio for Mac 使用笔记

    无法打开控制台运行程序 Project -> Project Options -> Run -> Configurations -> Default 勾选Run on exte ...

  8. Haskell语言学习笔记(19)File IO

    关于IO Action 类型为IO t. 运算时不执行,因而没有任何效果,只有执行时才会有效果,产生副作用. 一个IO Action只有在其他IO Action中才能被执行. 类型为IO t的IO A ...

  9. Android DevArt3:SingleTask启动模式探究:首先从MainActivity启动案例入口AActivity,并在A中启动BActivity,从B启动CActivity, 再从C中又启动AActivity, 最后在A中启动B,现在按两次back键,然后回到的是哪个Activity? 答案是,回到MainActivity。

    SingleTask启动模式探究 GitHub如题:首先从MainActivity启动案例入口AActivity,并在A中启动BActivity,从B启动CActivity,再从C中又启动AActiv ...

  10. ArcGIS案例学习笔记3_1_ArcMap编辑练习

    ArcGIS案例学习笔记3_1_ArcMap编辑练习 计划时间:第三天上午 目的:ArcMap编辑练习 教程: pdf page67 数据: gis_ex10/ex07 方法: 1.新建shp文件 目 ...