关于linux线程总结

来源:互联网 发布:ubuntu和redhat哪个好 编辑:程序博客网 时间:2024/06/04 08:07
 

关于linux 线程总结
什么是线程: 线程是进程中某一单一顺序的控制流。是程序执行的最小单元。
线程的优点:
1, 占CPU时间,资源少。
2, 一个进程中的多个线程共用一个地址空间,共享代码段,数据段,以及堆栈段。
编写线程程序时,需加<pthread.h>,编译时需加 –lpthread
创建线程的函数:
pthread_create(pthread_t *id, const pthread_attr_t *attr,void *(* start _rtn)(void),void *arg)
id:线程ID
attr: 线程属性(通常为空)
strat_rtn:线程要执行的函数
arg:执行函数的参数
线程退出函数
Pthread_exit(void *rval_ptr)
Rval_ptr:线程退场时返回值的指针。
线程等待函数
Pthread_join(pthread_t tid,void **rval_ptr)
Tid:等待退出的线程ID,实际上跟创建线程ID一样。
Rval_ptr :同上。
线程标识:
Pthread_t pthread_self(void )
获取调用线程的 线程标识符,类似getpid()
线程终止有两种情况:正常终止和非正常终止,线程主动调用pthread_exit或return 函数为正常退出。
非正常退出是在其他线程干扰下,或者自身出错,
非正常退出时要确保线程退出能释放占有资源,所以要调用
Pthread_clean_push 和 pthread_clean_pop 函数
Pthread_clean_push的调用点到pthread_clean_pop之间的程序段的终止动作(包括调用pthread_exit()和异常终止,不包含return,)都将执行pthread_clean_push()所指定的函数。
pthread_clean_push(void(*rtn)(void *),void *arg)
功能 :讲清楚函数入栈
Rtn 清除函数
Arg 函数形参
pthread_clean_pop(int n)
功能 :将函数弹出栈
执行到pthread_clean_pop是 当n为0 执行清除函数,非0不执行
例子:
1,创建线程
#include<pthread.h>
#include<stdio.h>
void *create(void *arg);

Int main()
{
 pthread_t id;
 Int a;
 a=pthread_create(&id,NULL,create,NULL);
 if(a)
{
 printf(“create pthread failure \n”);
 return 1;
}
    pthread_join(id,NULL);
 return 0;
}
void *create(void *arg)
{
     int i;
     for(i=0;i<4;i++)
{
     printf(“create %dst pthread success\n”,i);
}
    return (void *)0;
}


2,

#include<pthread.h>

#include<stdio.h>

#include<unistd.h>

void *create(void *arg);

int main(void)

{

    char *a="abcdefg";

    pthread_t id;

    int n;

    n=pthread_create(&id,NULL,create,(void *)a);

    if(n)

{

    printf("create pthread failure\n");

    return 1;

}

    pthread_join(id,NULL);

    return 0;

}

void *create(void *arg)

{

    char *p;

    p=(char *)arg;

    printf("the parameter passed from main function is %s \n",p);

    return (void *)0;

}

注意:关于pthread_create函数的第四个参数,是将第四个参数赋给线程函数的形参,并不是所谓形参返回值。

还有一个全局变量的例子

#include<stdio.h>

#include<pthread.h>

#include<unistd.h>

int a=5;

int main()

{

    int a=1;

    pthread_t id;

    int n;

    n=pthread_create(&id,NULL,create,NULL);

    if(n)

{

    printf("create pthread failure \n");

    return 1;

}

    pthread_join(id,NULL);

    printf("main function a=%d\n",a);

    return 0;

}

void *create(void *arg)
{

    printf("new pthread ...\n");

    printf("%d\n",a);

    a++;

    printf("%d\n",a);

    return 0;

}
有以上程序得出结论:线程函数所执行的只跟全局变量有关,跟局部变量没有关系,我在调试的时候,如果不设置全局变量,编译的时候就出错:线程函数中的a没有定义。

例子3

#include<stdio.h>

#include<unistd.h>

#include<pthread.h>

void *create(void *arg);

void *clean(void *arg);

int main(void)

{

    pthread_t id;

    int n;

    n=pthread_create(&id,NULL,(void *)create,(void *)1);

    if(n)

{

    printf("error\n");

    return 1;

}

    pthread_join(id,(void *)1);

    return 0;

}

void *create(void *arg)

{

    printf("pthread start  \n");

    pthread_cleanup_push((void *)clean,"thead first handler");

     pthread_cleanup_push((void *)clean,"thead second handler");

    printf("thread complete \n");

    if(arg)

{

    return ((void *)1);

}

    pthread_cleanup_pop(0);
       pthread_cleanup_pop(0);

     return ((void *)1);

}

void *clean(void *arg)

{

    char *c;

    c=(char *)arg;

    printf("cleanup : %s\n",c);

}

程序运行结果是:pthread start 

        thread complete

如果把线程函数中return ((void *)1);改成 pthread_exit((void *)1);

程序运行结果是:pthread start 

        thread complete

        thead second handler

        thead first handler

如果线程函数改成 pthread_cleanup_push((void *)clean,"thead first handler");

        pthread_cleanup_push((void *)clean,"thead second handler");

        printf("thread complete \n");

        pthread_cleanup_pop(1);
           pthread_cleanup_pop(1);

程序运行结果是:pthread start 

        thread complete

        thead second handler

        thead first handler

由此得出:pop和push是按先进后出原则,当pop push中间代码含有return 不会执行push中所执行函数,若调用pthread_exit()和异常终止会执行push指定函数。pop push中间代码无退出,且pop参数为非0,则会执行push所指定函数。