线程基础

线程是cpu的调度单位,不拥有系统资源,和属于同一进程的其他线程共享进程的资源。

一、线程标识

进程id在整个系统中是唯一的,但线程id不同,只在它所属的进程环境中有效。

进程id用pid_t数据类型来表示,是一个非负整数,线程id用pthread_t数据类型来表示,实现的时候可以用一个结构来代表pthread_t数据类型。因此必须使用函数来对两个线程id进行比较。

#include <pthread.h>
int pthread_equal(pthread_t tid1,pthread_t tid2);
//返回值:若相等则返回非0值,否则返回0

线程可以通过调用pthread_self函数获得自身的线程id

#include <pthread.h>
pthread_t pthread_self(void);

二、线程创建

调用pthread_create函数创建新线程

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr,void *(*start_rtn)(void*),void *restrict arg);

当pthread_create成功返回(返回0)时,由tidp指向的内存单元被设置为新创建线程的线程id。attr参数用于定制各种不同的线程属性,NULL代表默认属性的线程。

新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg,如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg参数传入。

线程创建时并不能保证哪个线程会先运行:是新创建的线程或调用线程。

#include <stdio.h>
#include <pthread.h>

pthread_t ntid;

void printids(const char *s)
{
        pid_t pid;
        pthread_t tid;

        pid=getpid();
        tid=pthread_self();
        printf("%s pid %u tid %u\n",s,(unsigned int)pid,(unsigned int)tid);
}

void *thr_fn(void *arg)
{
        printids("new thread:");
        return ((void *)0);
}

int main(void)
{
        int err;
        err=pthread_create(&ntid,NULL,thr_fn,NULL);
        printids("main thread:");
        sleep(1);
        exit(0);
}

输出:

main thread: pid 4014 tid 3075741376
new thread: pid 4014 tid 3075738432

上述代码中,主线程需要休眠,如果主线程不休眠,它就可能退出,这样在新线程有机会运行之前整个进程就已经停止了。

新线程不能安全地使用ntid,如果新线程在主线程调用pthread_create返回之前就运行了,那么新线程看到的是未经初始化的ntid内容。

三、线程终止

单个线程在不终止整个进程的情况下停止它的控制流:

1)线程只是从启动例程中返回,返回值是线程的退出码

2)线程可以被同一进程中的其他线程取消

3)线程调用pthread_exit

#include <pthread.h>
void pthread_exit(void *rval_ptr)

rval_ptr包含线程的退出状态,其他线程可以通过调用pthread_join函数访问到这个指针。

#include <pthread.h>
int pthread_join(pthread_t thread,void **rval_ptr)
//返回值:若成功则返回0,否则返回错误编号

 

#include <apue.h>
#include <pthread.h>

void *thr_fn1(void *arg)
{
        printf("thread 1 returning\n");
        return((void *)1);
}

void *thr_fn2(void *arg)
{
        printf("thread 2 exiting\n");
        pthread_exit((void *)2);
}

int main()
{
        pthread_t tid1,tid2;
        void *tret;

        pthread_create(&tid1,NULL,thr_fn1,NULL);
        pthread_create(&tid2,NULL,thr_fn2,NULL);

        pthread_join(tid1,&tret);
        printf("thread 1 exit code %d\n",(int)tret);

        pthread_join(tid2,&tret);
        printf("thread 2 exit code %d\n",(int)tret);

        exit(0);
}

当一个线程通过调用pthread_exit退出或者简单地从启动例程中返回时,进程中的其他线程可以通过调用pthread_join函数获得该线程的退出状态

 

 

 

posted @ 2014-07-03 13:25  合唱团abc  阅读(172)  评论(0编辑  收藏  举报