加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

线程的创建、分离和取消

(2017-10-30 18:25:38)
标签:

it

分类: UnixC
1.线程的创建
系统提供了函数pthread_create(3)用于创建线程
pthread_create(3)
原型:
   #include <pthread.h>
   int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

Compile and link with -pthread.

功能:创建一个新的线程
参数:
    thread          存放线程ID  的缓冲区, pthread_t 即unsigned long int
    attr          
使用函数pthread_attr_init进行初始化结构体,如果为NULL,则使用默认属性进行初始化,pthread_attr_t可能是整型,也可能是结
构体,因实现而异。
    start_routine   线程的执行函数,参数和返回值类型都是void *。启动线程其实就是调用一个函数,只不过是在一个独立的线程中调用的,函数一旦返回,线程即高结束。
    arg             线程执行函数start_routine的唯一参数。线程过程函数的调用者是系统内核,因此需要预先将参数存储到系统内核中。
返回值:
    成功:0
    错误:返回错误码,并且*thread的内容不确定
说明:
1)main函数可以被视为主线程的线程过程函数。main函数一旦返回,主线程即告失败,主线程一旦结束,进程即告结束。进程一旦结束,其所有的子线程统统结束。
2)应设法保证在线程过程函数执行期间,传递给它的参数arg所指向的目标持久有效。
3)传递给线程过程函数的参数是一个泛型指针void *,它可以指向任何类型的数据:基本类型变量,结构体型变量或者数组型变量等等,但必须保证在线程过程函数执行期间,该指针所执向的目标变量持久有效,直到线程过程函数不在使用为止。
4)调用pthread_create函数的代码在用户空间,线程过程函数的代码也在用户空间,但偏偏创建线程的动作由系统内核完成。因此传递给线程过程函数的参数也不得不经由系统内核传递给线程过程函数。pthread_create函数的arg参数负责将线程过程函数的参数带入系统内核。
示例:
#include <stdio.h>
#include <pthread.h>

//线程执行函数
void *doit(void *arg)
{
    printf("%s\n", (char *)arg);
    return NULL;
}

int main(void)
{
    int p;
    pthread_t tid;
    //创建新的线程
    p=pthread_create(&tid, NULL, doit, "new");
    if(p!=0)
    {
        printf("pthread_create failed.\n");
    }

    //休眠两秒保证新建线程的执行,避免主线程先执行,结束进程。
    sleep(2);
    doit("main");
    return 0;
}

tarena@ubuntu:~/桌面/lzh/UC/day15$ gcc pthread_c.c -lpthread


---------------------------------------------------------------------
2.pthread_self(3)     获取线程自己的tid
原型:
       #include <pthread.h>
       pthread_t pthread_self(void);
       Compile and link with -pthread.

功能:获取当前线程的tid,和pthread_create函数中的参数*thread的值一样
参数:woid
返回值:总是成功,返回线程id
示例:
pthread_t thread = pthread_self();
printf("线程ID:%ul\n", thread);

3.pthread_equal
原型:
#include <pthread.t>
int pthread_equal(pthread_t t1, pthread_t t2);
功能:
判断线程ID是否相等
参数:
t1:线程ID
t2:线程ID
返回值:
t1=t2表示线程ID相等,返回非零,否则返回0
说明:
并非所有实现的pthread_t都是unsigned long int类型,有些可能是结构体类型,不能用==判断其是否相等。
示例:
printf("%d\n", pthread_equal(t1, t2));
---------------------------------------------------------------------
4.pthread_joid(3)
原型:
    #include <pthread.h>
    int pthread_join(pthread_t thread, void **retval);

    Compile and link with -pthread.

功能:等待一个线程终止并与之汇合,同时回收该线程的相关资源。
参数:
    thread:指定了等待汇合的线程的id
    retval:存放输出线程过程函数的返回值。为了获得线程过程函数返回的一级泛型指针,可以同样定义一个一级泛型指针,并将其地址通过pthread_join函数的二级泛型指针参数retval传入函数,并有函数在thread线程终止以后,将其线程过程函数返回的一级指针填入二级指针的目标。
返回值:
    成功:0
    错误:非0的错误码
说明:
1)从线程过程函数中返回值的方法
--线程过程函数将所需要返回的内容放在一块内存中,返回该内存的地址,同时保证这块内存,在函数返回即线程结束以后依然有效。
--若retval参数非NULL,则pthread_join函数将线程过程函数所返回的指针,拷贝到该参数所执向的内存中。
--若线程过程函数所返回的指针指向动态分配的内存,则还需保证在用过该内存之后释放它。

---------------------------------------------------------------------
5.线程的分离
pthread_detach(3)
原型:
    #include <pthread.h>
    int pthread_detach(pthread_t thread);

    Compile and link with -pthread.

功能:
使指定的线程进入分离状态。
参数:
    thread:
返回值:
    成功:0
    错误:非0错误码
说明:
该函数是thread线程进入分离状态。处于分离状态的线程一旦终止,其线程资源即被系统自动回收。处于分离状态的线程不能被pthread_join函数汇合。
示例:
1) pthread_detach(pthread_self());
2)
#include <stdio.h>
#include <p_net.h>
#include <pthread.h>

void *doit(void *arg)
{
    printf("new thread....\n");
    return NULL;
}

int main(void)
{
    pthread_t tid;
    pthread_create(&tid, NULL, doit, NULL);

    pthread_detach(tid);
    sleep(2);
    return 0;
}

---------------------------------------------------------------------
4.return 和 exit(3)的区别
return只是函数的返回,在线程处理函数中,只是代表线程的结束,不会结束进程
exit(3)代表的是进程的结束,进程中的所有线程就终止了。

在线程的处理函数中一定不要使用exit,使用函数pthread_exit(3)来终止一个线程
pthread_exit(3)
原型:
       #include <pthread.h>
       void pthread_exit(void *retval);
 
       Compile and link with -pthread.
 
功能:令调用线程终止运行。
参数:
    retval:指定传递给另一个线程的值,那个线程调用pthread_join(3)接受这个值,相当于线程过程函数的返回值。
返回值:
    不返回给调用者
说明:
1)在线程过程函数或者被线程过程函数直接或间接调用的函数中,调用pthread_exit函数,其效果斗鱼在线程过程函数中执行returen语句的效果一样--终止调用线程。
2)在任何线程中调用exit函数,被终止的都是进程,当然随着进程的终止,隶属于该进程的包括调用线程在内的所有线程都一并终止。
3)调用pthread_exit函数之后,进程的共享资源不会释放,只有当进程的最后一个线程结束的时候,整个进程才退出,才会调用atexit(3)指定的函数。        

---------------------------------------------------------------------
5.pthread_cancel(3)
原型:
       #include <pthread.h>
       int pthread_cancel(pthread_t thread);

       Compile and link with -pthread.

功能:给线程发送取消请求
参数:thread:指定接收请求的线程id
返回值:
    成功:0
    错误:非0的错误码
注意:
1)该函数是向线程发出请求,并不等待线程终止。
2)缺省情况下,线程在收到取消请求以后,并不会立即终止,而是仍继续运行,直到其达到某个取消点。在取消点处,线程检查其自身是否已被取消,若是则立即终止。
3)当线程调用一些特定函数时,取消点会出现。
4)使用pthread_cancel终止的线程,在使用pthread_joid(3)获取线程退出信息的时候,获取到的是PTHREAD_CANCELED作为线程退出状态码。
5)线程的汇合是判断线程取消是否完成的唯一方式。

---------------------------------------------------------------------             
6.pthread_setcancelstate
原型:
#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
功能:设置调用线程的取消状态
参数:
state 取消状态,可取以下值
PTHREAD_CANCEL_ENABLE 接受取消请求(缺省)
PTHREAD_CANCEL_DISABLE 忽略取消请求
oldstate:输出原取消状态,可取NULL
返回值:
成功:0
失败:返回错误码

---------------------------------------------------------------------
7.pthread_setcanceltype
原型:
#include <pthread.h>
int pthread_setcanceltype(int type, int *oldtype);
功能:设置调用线程的取消状态
参数:
type 取消类型,可取以下值
PTHREAD_CANCEL_DEFERRED        延迟取消(缺省)
被取消线程在接收到取消请求之后并不立即终止,而是一直等到执行了特定函数之后在终止。
PTHREAD_CANCEL_ASYNCHRONOUS 异步取消
被取消线程可以在任意时刻终止,而不是非遇到取消点。
oldtype:输出原取消状态,可取NULL
返回值:
成功:0
失败:返回错误码

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有