使用多线程的理由之一是和进程相比,它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立 的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相 同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要 的时间。
使用多线程的理由之二是线程间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不 仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数 据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是 编写多线程程序时最需要注意的地方。
1、函数语法简述。
头文件: pthread.h
函数原型: int pthread_create (pthread_t* thread, pthread_attr_t* attr,
void* (start_routine)(void*), void* arg);
函数传入值: thread: 线程标识符
attr: 线程属性设置
start_routine:线程函数入口
arg:传递给线程函数的参数
返回值: 0: 成功
-1: 失败
调用此函数可以创建一个新的线程,新线程创建后执行start_routine 指定的程序。其中参数attr是用户希望创建线程的属性,当为NULL时表示以默认的属性创建线程。arg是向start_routine 传递的参数。当成功创建一个新的线程时,系统会自动为新线程分配一个线程ID号,并通过pthread 返回给调用者。
pthread_exit
头文件: pthread.h
函数原型: void pthread_exit(void *value_ptr);
函数传入值:retval:pthread_exit()调用者线程的返回值,可又其他函数如pthread_join来检索获取。
调用该函数可以退出线程,参数value_ptr是一个指向返回状态值的指针。
phread_join
头文件: pthread.h
函数原型: int pthread_join (pthread_t* thread, void** thread_return);
函数传入值:thread:等待线程的标识符。
thread_return:用户定义的指针,用来存储被等待线程的返回值(不为NULL值);
函数返回值:成功: 0
失败:-1
这个函数的作用是等待一个线程的结束。调用pthread_join()的线程将被挂起直到线程ID为参数thread 指定的线程终止。
pthread_self(void);
为了区分线程,在线程创建时系统为其分配一个唯一的ID号,由pthread_create()返回给调用者,也可以通过pthread_self()获取自己的线程ID。
linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,
如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。
若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。
unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.
pthread_mutex_init
头文件: <pthread.h>
函数原型: int pthread_mutex_init (pthread_mutex_t* mutex,
const pthread_mutexattr_t* mutexattr);
函数传入值: mutex:互斥锁。
mutexattr:PTHREAD_MUTEX_INITIALIZER:创建快速互斥锁。
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP:创建递归互斥锁。
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP:创建检错互斥锁。
函数返回值: 成功:0
出错:-1
上锁函数:
int pthread_mutex_lock(pthread_mutex_t* mutex);
int pthread_mutex_trylock (pthread_mutex_t* mutex);
int pthread_mutex_unlock (pthread_mutex_t* mutex);
int pthread_mutex_destroy (pthread_mutex_t* mutex);
函数传入值: mutex:互斥锁。
函数返回值: 同上。
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<pthread.h> #define BUFFER_SIZE 8 struct prodcons { int buffer[BUFFER_SIZE]; pthread_mutex_t lock; //互斥LOCK int readpos , writepos; pthread_cond_t notempty; //缓冲区非空条件判断 pthread_cond_t notfull; //缓冲区未满条件判断 }; 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; } void put(struct prodcons* b,int data){ pthread-_mutex_lock(&b->lock); if((b->writepos + 1) % BUFFER_SIZE == b->readpos) { pthread_cond_wait(&b->notfull, &b->lock) ; } b->buffer[b->writepos]=data; b->writepos++; if(b->writepos >= BUFFER_SIZE) b->writepos=0; pthread_cond_signal(&b->notempty); pthread_mutex_unlock(&b->lock); } int get(struct prodcons *b){ int data; pthread_mutex_lock(&b->lock); if(b->writepos == b->readpos) { 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); pthread_mutex_unlock(&b->lock); return data; } #define OVER (-1) struct prodcons buffer; void *producer(void *data) { int n; for(n = 0; n < 10000; n++) { printf("%d \n", n) ; put(&buffer, n); } put(&buffer, OVER); return NULL; } void *consumer(void * data) { int d; while(1) { d = get(&buffer); if(d == OVER) break; printf("%d\n", d); } return NULL; } int main(void) { pthread_t th_a, th_b; void *retval; init(&buffer); pthread_create(&th_a, NULL, producer, 0); pthread_create(&th_b, NULL, consumer, 0); pthread_join(th_a, &retval); pthread_join(th_b, &retval); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u014082714/article/details/48057323