linux下线程

线程与进程的关系:
之前转载的微信文章,进程与线程的差别已经说得比較清楚了。能够查看之前转载的文章。linux进程与线程的差别。
创建一个线程:
#include<pthread.h>
               int pthread_creat(pthread_t * thread,pthread_attr_t * attr,void *(*stat_routine)(void *),void *arg);
               惯例先写上函数原型:
參数:第一个參数pthread_t * thread 是一个指针,当进程创建时用来返回进程的ID。

    第二个參数pthread_attr_t * attr 用于指示线程的属性,默认就是NULL。
                                    第三个參数void *(*stat_routine)(void *),void *arg 这个參数为一个函数指针,指向线程创建后要调用的函数。
                                    第四个參数void *arg  该參数指向传递给线程函数的參数。
                      创建成功后返回0,失败返回错误码(非常多种。

。。cha)


几个其它实用的系统调用:
pthread_t pthread_self(void )                                                       获取本线程的ID
        int pthread_equal(pthread_t  thread,pthread_t thread2)           推断两个线程的ID是否指向同一个ID
        int pthread_once (pthread_once_t *once_count,void(*int_routine)(void))    用来保证线程的函数仅仅运行一次

一个运行一次函数的样例
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h> pthread_once_t once = PTHREAD_ONCE_INIT; //指定參数位仅仅运行一次 void run(void) //演示样例线程函数
{
printf("function run is runing in thread %d\n",pthread_self());
} void *thread1(void *arg)
{
pthread_t thid = pthread_self(); //接受而且打印当前线程的ID
printf("current thread id is %d\n",thid); //调用运行线程函数仅仅运行一次,接受一个标志參数和一个目标函数的指针
pthread_once(&once,run);
printf("thread1 ends\n"); //打印函数调用结束提示信息
} void *thread2(void *arg)
{
pthread_t thid = pthread_self(); //接受而且打印当前线程ID
printf("current thread is ID %u\n",thid);
pthread_once(&once,run); //调用函数同上以一个函数结构。可是这里并不会成功调用由于仅仅运行一次
printf("thread2 ends\n"); //打印函数调用结束信息
}
int main()
{
pthread_t thid1,thid2; //定义两个线程ID
pthread_create(&thid1,NULL,thread1,NULL); //创建线程。调用上边的函数1和函数2
pthread_create(&thid2,NULL,thread2,NULL);
sleep(3); //主线程(进程)暂停3秒后继续运行
printf("main thread exit!\n");
exit(0);
}

run 函数在线程thread1 中仅仅执行了一次。尽管thread2也调用了,然而并没有什么用


线程的属性:
pthread_attr_t 结构体

typedef struct

{

int                              detachstate;   线程的分离状态

int                              schedpolicy;  线程调度策略

struct sched_param           schedparam;  线程的调度參数

int                              inheritsched;  线程的继承性

int                               scope;       线程的作用域

size_t                          guardsize;   线程栈末尾的警戒缓冲区大小

int                               stackaddr_set;

void *                         stackaddr;   线程栈的位置

size_t                          stacksize;    线程栈的大小

}pthread_attr_t;



线程的终止:
两种方式:
1.通过return返回
                        2.调用库函数
#include<pthread.h>
                       void pthread_exit(void *retval);
              当调用退出函数时需注意:
1.调用exit( )一个线程死亡,这个进程也会跟着死亡。
                2假设调用本函数那么不过主线程死亡,进程依旧存活。


pthread_join(pthread_t th,void * thread_return);
            这个函数用于等待一个线程的结束。

         
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h> void assisthread(void *arg) //演示样例线程函数
{
printf("i am nothing helping to do some thing\n");
sleep(3); //暂停三秒
//pthread_exit(0);
//线程结束
exit(0);
} int main()
{
pthread_t assisthid;
int status ; pthread_create(&assisthid,NULL,(void *)assisthread,NULL); //创建线程
pthread_join(assisthid,(void *)&status); //等待指定线程结束
printf("assistthread's exit is caused %d\n",status); return 0;

私有数据:

这个比較有意思。再说之前最好还是来说说error 这个东西。这是存储程序错误时返回的错误码的一个全局变量。之前上课时,有一个同学提问假设错误同一时候发生。那么两个进程都向这个变量中写入数据,会发生什么事情?会锁死。还是会覆盖?首先,这种事情基本不会发生。由于CPU仅仅有一个,就算有两个CPU同一时候处理这两个进程也非常难发生这种事,由于CPU的时间能够精确到10^-9次方秒。两个时间撞在一起真是比买彩票中奖还难。更何况就算发生了也没事。这是由与error事实上是一个私有数据。全局变量有这个变量名字叫做”键“,而每个线程都有一个error用来存储值,俗称一键多值。每个error是不影响的。
一段代码:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h> pthread_key_t key; //定义全局变量,键 void *thread2(void *arg) //第二个函数
{
int tsd = 5; //自己线程的私有数据
printf("thread %d is runing \n",pthread_self());
pthread_setspecific(key,(void *)tsd); //设置一个私有数据
printf("thread %d return %d\n",pthread_self(),pthread_getspecific(key));
} void *thread1(void *arg)//创建线程一然后调用函数二创建还有一个线程
{
int tsd = 0;
pthread_t thid2; printf("thread %d is runing\n",pthread_self());
pthread_setspecific(key,(void *)tsd);
pthread_create(&thid2,NULL,thread2,NULL);
sleep(5);
printf("thread %d return %d\n",pthread_self(),pthread_getspecific(key));
} int main()
{
pthread_t thid1;
printf("main thread begins running\n");
pthread_key_create(&key,NULL); //创建一个键
pthread_create(&thid1,NULL,thread1,NULL); //调用函数一创建线程1
sleep(3);
pthread_key_delete(key); //删除键
printf("main thread exit\n");
return 0;
}

终于打印的值一个是5 一个是0,足见这是各个线程私有的数据。



linux下线程的更多相关文章

  1. Linux 下线程的理解

    2017-04-03 最近深入研究了下Linux线程的问题,发现自己之前一直有些许误解,特记之…… 关于Linux下的线程,各种介绍Linux的书籍都没有深入去解释的,或许真的如书上所述,Linux本 ...

  2. linux下线程调用sleep,进程挂起

    http://blog.csdn.net/horstlinux/article/details/7911457 http://blog.csdn.net/eroswang/article/detail ...

  3. linux下线程的两种封装方式

    在网络编程的时候往往需要对Linux下原生的pthread库中的函数进行封装,使其使用起来更加方便,封装方法一般有两种:面向对象和基于对象,下面将分别介绍这两种方式,最后统一分析这两种方式的优缺点: ...

  4. Linux下线程同步的几种方法

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 锁机制是同一时刻只允许一个线程执行一个关键部分的代码.  1. 初始化锁 int pthrea ...

  5. linux下线程调试 ulimit core

    在linux 下写线程程序的同学预计都遇到过找bug找到崩溃的情况.多线程情况下bug的追踪实在是不easy. 如今我来介绍一个好用的方法 ulimit core. 先简介一下ulimit是个什么(你 ...

  6. Linux下线程池的理解与简单实现

    首先,线程池是什么?顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池. 其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程 ...

  7. linux下线程的分离和结合属性

    在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached).一个可结合的线程能够被其他线程收回其资源和杀死:在被其他线程回收之前,它的存储器资源(如栈)是不释放的.相反, ...

  8. linux 下线程错误查找,与线程分析命令

    一. 使用top和jstack查找线程错误 我们使用jdk自带的jstack来分析.当linux出现cpu被java程序消耗过高时,以下过程说不定可以帮上你的忙: 1.top查找出哪个进程消耗的cpu ...

  9. [转] unix/linux下线程私有数据实现原理及使用方法

     在维护每个线程的私有数据的时候,我们可能会想到分配一个保存线程数据的数组,用线程的ID作为数组的索引来实现访问,但是有一个问题是系统生成的线程 ID不能保证是一个小而连续的整数,并且用数组实现的时候 ...

随机推荐

  1. ios除去可变字符串中的某些字符

    //除去字符串中的"111@" NSMutableString *str = [[NSMutableString alloc]initWithFormat:@"111@s ...

  2. 利用ajax异步处理POST表单中的数据

    //防止页面进行跳转 $(document).ready(function(){   $("#submit").click(function(){    var str_data= ...

  3. NFS的搭建(sudo apt-get install nfs-kernel-server),TFTP服务器(sudo apt-get install tftpd-hpa tftp-hpa)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Osean_li/article/details/53240705 ***************** ...

  4. python网络编程三次握手和四次挥手

    TCP是因特网中的传输层协议,使用三次握手协议建立连接.当主动方发出SYN连接请求后,等待对方回答SYN+ACK[1],并最终对对方的 SYN 执行 ACK 确认.这种建立连接的方法可以防止产生错误的 ...

  5. Python学习小计

    1.初学Python最好选择2.7版本,因为大部分Python书籍的示例代码是基于这个版本的 2.Python安装可以参考百度经验完成 如果在电脑上同时安装2个版本,则CMD启动时只需要: py -2 ...

  6. ubuntu 14.04开机出现错误“Error found when loading /root/.profile”解决

    在刚修改完root权限自动登录后,发现开机出现以下提示: Error found when loading /root/.profile stdin:is not a tty ………… 解决方法:在终 ...

  7. Jq自定义的方法绑定树结构

    1.先上效果图  (借鉴博客) 2.这边不做样式的只做结构 function toTreeData(data) { var pos = {}; var tree = []; var i = 0; wh ...

  8. js闭包概念

    含义:闭包是一个概念,它描述了函数执行完毕内存释放后,依然内存驻留的一个现象,只要把握这个核心概念,闭包就不难理解了 function a(){      var i=0;      function ...

  9. CSS3背景 制作导航菜单综合练习题

    CSS3背景 制作导航菜单综合练习题 小伙伴们,根据所学知识,使用CSS3实现下图的导航菜单效果 任务 1.制作导航圆角 提示:使用border-radius实现圆角 2.制作导航立体风格 提示:使用 ...

  10. SwipeRefreshLayout的使用,下拉刷新

    1. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android ...