线程函数

主要的多线程API
1、 线程创建函数:
int pthread_create (pthread_t * thread_id, __const pthread_attr_t * __attr,
void *(*__start_routine) (void *),void *__restrict __arg);
2、 获得父进程ID:
pthread_t pthread_self (void)
3、 测试两个线程号是否相同:
int pthread_equal (pthread_t __thread1, pthread_t __thread2)
4、 线程退出:
void pthread_exit (void *__retval)
5、 等待指定的线程结束:
int pthread_join (pthread_t __th, void **__thread_return)
6、 互斥量初始化:
pthread_mutex_init (pthread_mutex_t *,__const pthread_mutexattr_t *)
7、 销毁互斥量:
int pthread_mutex_destroy (pthread_mutex_t *__mutex);
8、 再试一次获得对互斥量的锁定(非阻塞):
int pthread_mutex_trylock (pthread_mutex_t *__mutex);
9、 锁定互斥量(阻塞):
int pthread_mutex_lock (pthread_mutex_t *__mutex);
10、解锁互斥量
int pthread_mutex_unlock (pthread_mutex_t *__mutex)
11、条件变量初始化
int pthread_cond_init (pthread_cond_t *__restrict __cond,
__const pthread_condattr_t *__restrict __cond_attr)
12、销毁条件变量COND
int pthread_cond_destroy (pthread_cond_t *__cond)
13、唤醒线程等待条件变量
int pthread_cond_signal (pthread_cond_t *__cond)
14、等待条件变量(阻塞)
int pthread_cond_wait (pthread_cond_t *__restrict __cond,
pthread_mutex_t *__restrict __mutex)
15、在指定的时间到达前等待条件变量
int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
pthread_mutex_t *__restrict __mutex,
__const struct timespec *__restrict __abstime)

PTHREAD 库中还有大量的API 函数,用户可以参考其他相关书籍。

主要函数说明
pthread_create 线程创建函数
int pthread_create (pthread_t * thread_id,__const pthread_attr_t * __attr,
void *(*__start_routine) (void *),void *__restrict __arg);
线程创建函数第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第
三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。这里,我们的函数
thread 不需要参数,所以最后一个参数设为空指针。第二个参数我们也设为空指针,这样将
生成默认属性的线程。当创建线程成功时,函数返回0,若不为0 则说明创建线程失败,常
见的错误返回代码为EAGAIN 和EINVAL。前者表示系统限制创建新的线程,例如线程数目过
多了;后者表示第二个参数代表的线程属性值非法。创建线程成功后,新创建的线程则运行
参数三和参数四确定的函数,原来的线程则继续运行下一行代码。

16、pthread_join 函数
用来等待一个线程的结束。函数原型为:
int pthread_join (pthread_t __th, void **__thread_return)
第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存
储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等
待的线程结束为止,当函数返回时,被等待线程的资源被收回。
17、pthread_exit 函数
一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线
程也就结束了;另一种方式是通过函数pthread_exit 来实现。它的函数原型为:
void pthread_exit (void *__retval)
唯一的参数是函数的返回代码,只要pthread_join 中的第二个参数thread_return 不
是NULL,这个值将被传递给thread_return。最后要说明的是,一个线程不能被多个线程等
待,否则第一个接收到信号的线程成功返回,其余调用pthread_join 的线程则返回错误代
码ESRCH。

条件变量
使用互斥锁来可实现线程间数据的共享和通信,互斥锁一个明显的缺点是它只有两种状
态:锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了
互斥锁的不足,它常和互斥锁一起使用。使用时,条件变量被用来阻塞一个线程,当条件不
满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件
变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重
新锁定互斥锁并重新测试条件是否满足。一般说来,条件变量被用来进行线线程间的同步。

18、pthread_cond_init 函数
条件变量的结构为pthread_cond_t,函数pthread_cond_init()被用来初始化一个条
件变量。它的原型为:
int pthread_cond_init (pthread_cond_t * cond, __const pthread_condattr_t *
cond_attr)
其中cond 是一个指向结构pthread_cond_t 的指针,cond_attr 是一个指向结构
pthread_condattr_t 的指针。结构pthread_condattr_t 是条件变量的属性结构,和互斥锁
一样我们可以用它来设置条件变量是进程内可用还是进程间可用,默认值是PTHREAD_
PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用。注意初始化条件变量只有
未被使用时才能重新初始化或被释放。释放一个条件变量的函数为pthread_cond_ destroy
(pthread_cond_t cond)。

19、pthread_cond_wait 函数
使线程阻塞在一个条件变量上。它的函数原型为:
extern int pthread_cond_wait (pthread_cond_t *__restrict__cond,
pthread_mutex_t *__restrict __mutex)
线程解开mutex 指向的锁并被条件变量cond 阻塞。线程可以被函数
pthread_cond_signal 和函数pthread_cond_broadcast 唤醒,但是要注意的是,条件变量只
是起阻塞和唤醒线程的作用,具体的判断条件还需用户给出,例如一个变量是否为0 等等,
这一点我们从后面的例子中可以看到。线程被唤醒后,它将重新检查判断条件是否满足,如
果还不满足,一般说来线程应该仍阻塞在这里,被等待被下一次唤醒。这个过程一般用while
语句实现。


20、pthread_cond_timedwait 函数
另一个用来阻塞线程的函数是pthread_cond_timedwait(),它的原型为:
extern int pthread_cond_timedwait __P ((pthread_cond_t *__cond,
pthread_mutex_t *__mutex, __const struct timespec *__abstime));
它比函数pthread_cond_wait()多了一个时间参数,经历abstime 段时间后,即使条件变
量不满足,阻塞也被解除。

21、函数pthread_cond_signal
函数pthread_cond_signal()的原型为:
extern int pthread_cond_signal (pthread_cond_t *__cond);
它用来释放被阻塞在条件变量cond 上的一个线程。多个线程阻塞在此条件变量上时,哪一
个线程被唤醒是由线程的调度策略所决定的。要注意的是,必须用保护条件变量的互斥锁来
保护这个函数,否则条件满足信号又可能在测试条件和调用pthread_cond_wait 函数之间被
发出,从而造成无限制的等待。


//linux下简单多线程 
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include"pthread.h"

#define BUFFER_SIZE 16

struct prodcons
{
       int buffer[BUFFER_SIZE];
       pthread_mutex_t lock;//mutex ensuring exclusive access to buffer
       int readpos,writepos;//position for reading and writing
       pthread_cond_t notempty;//signal when buffer is not empty
       pthread_cond_t notfull;//signal when buffer is not full
};
//initialize a buffer
void init(struct prodcons* b)
{
     pthread_mutex_init(&b->lock,NULL);
     pthread_cond_init(&b->notempty,NULL);
     pthread_cond_init(&b->notfull,NULL);
     b->readpos=0;
     b->writepos=0;
}
//store an integer in the buffer
void put(struct prodcons* b, int data)
{
     pthread_mutex_lock(&b->lock);
     //wait until buffer is not full
     while((b->writepos+1)%BUFFER_SIZE==b->readpos)
     {
        printf("wait for not full\n");
        pthread_cond_wait(&b->notfull,&b->lock);
     }     
     
     b->buffer[b->writepos]=data;
     b->writepos++;
     pthread_cond_signal(&b->notempty); //signal buffer is not empty
     pthread_mutex_unlock(&b->lock);
}
//read and remove an integer from the buffer
void get(struct prodcons* b)
{
     int data;
     pthread_mutex_lock(&b->lock);
     //wait until buffer is not empty
     while(b->writepos==b->readpos)
     {
        printf("wait for not empty\n");
        pthread_cond_wait(&b->notempty,&b->lock);
     }     
     
     data=b->buffer[b->readpos];
     b->readpos++;
     if(b->readpos>=BUFFER_SIZE) b->readpos=0;
     pthread_cond_signal(&b->notfull);//signal buffer is not full
     pthread_mutex_unlock(&b->lock);
     return data;
}

#define OVER -1

struct prodcons buffer;

void * producer(void * data)
{
     int n;
     for(n=0;n<1000;++n)
     {
       printf("put-->%d\n",n);
       put(&buffer,n);
     }
     put(&buffer,OVER);
     printf("producer stopped\n");
     return NULL;
}

void * consumer(void * data)
{
     int n;
     while(1)
     {
       d=get(&buffer);
       if(d==OVER) break;
       printf("%d-->get\n",d);
     }
     printf("consumer stopped\n");
     return NULL;
}

int main()
{
    pthread_t tha,thb;
    void * retval;
    
    init(&buffer);
    pthread_creare(&tha,NULL,producer,0);
    pthread_creare(&thb,NULL,consumer,0);
    
    pthread_join(tha,&retval);
    pthread_join(thb,&retval);
    
    return 0;
}

posted on 2015-06-15 13:37  小小鸟儿!  阅读(204)  评论(0编辑  收藏  举报