介绍
函数
pthread_create()
这个函数创建一个线程,原型如下:
#include <pthread.h>
int pthread_create (pthread_t *thread, pthread_attr_t *attr,\
void * (*start_routine) (void *), void *arg);
一共需要四个参数传递给 pthread_create 函数,调用成功返回 0,否
则返回其他值。
- 线程标识符
- 这是第一个参数,是一个指针,指向一个
pthread_t类型的数据。创建一个线程的时候,这个指针指向的变 量里面会被写入一个标识符,以后可以通过这个标识符来引用此线 程。 - 线程属性
- 第二个参数设置线程的属性,通常可以传递
NULL给这个参数。 - 执行函数
- 第三个参数就是本线程要执行的函数,这是一个函数指 针,这个函数的形参可以是任何类型的指针(void ),返回值也可 以是任何类型的指针 (void )。
- 传递给执行函数的参数
- 第四个参数是一个指向任意类型的指针, 传递给第三个参数作为参数。
pthread_exit()
pthread_exit() 用于线程退出,可以指定返回值,以便其他线程通过
pthread_join() 函数获取该线程的返回值。 return ,是函数返回,
不一定是线程函数! 只有线程函数 return,线程才会退出 exit()
是进程退出,如果在线程函数中调用 exit ,那此线程的进程也就挂了。
会导致该线程所在进程的其他线程也挂掉,比较严重。
#include <pthread.h> void pthread_exit ( void *retval );
pthread_join()
相当于进程中的 wait() 函数,第一个参数是要等待的线程,它是用
pthread_create() 创建的线程标识符。第二个参数是一个指针,这个指
针指向线程的返回值。成功返回0,出错返回错误代码。
#include <pthread.h> int pthread_join (pthread_t th, void **thread_return);
线程同步
信号量同步
信号量函数名字都以 sem_ 开头,线程中使用的基本信号量函数有四个。
创建信号量 sem_init()
#include <semaphore.h> int sem_init (set_t *sem, int pshared, unsigned int value);
对由 sem 指定的信号量进行初始化,设置好它的共享项,给它一个整数
类型的初始值。 pshared 参数控制着信号量的类型,如果其值为0,则
表示它是当前进程的局部信号量;否则,其他进程就可以共享这个信号量。
sem_wait() 和 sem_post()
#include <semaphore.h> int sem_wait( set_t *sem); int sem_post( set_t *sem);
sem_post() 给信号量的值加上一个 "1"; sem_wait() 给一个信号量减
去 "1",永远等待信号量的值不为零才执行这个动作。
清理信号量 sem_destroy()
#include <semaphore.h> int sem_destroy (sem_t * sem);
下面的例子是《Linux程序设计》上的,略作修改。这个例子用到了我们
上面介绍的函数。能很好的理解线程间的信号量通信方式。记住,初始
化信号量一般设置其值为0,等待的线程如果需要其他“线程”先执行,以
便得到自己想要的数据,就使用 sem_wait() 函数等待。别的线程在准
备好数据后,就使用 sem_post() 函数增加信号量的值。最后注销创建
的信号量是个好习惯!
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <semaphore.h> #include <pthread.h> void * thread_func (void *arg); sem_t bin_sem; #define WORK_SIZE 1024 char work_area[WORK_SIZE]; int main() { int res; pthread_t thread_one; void *thread_result; res=sem_init(&bin_sem,0,0); if (res != 0) { perror("信号初始化失败!"); exit(EXIT_FAILURE); } res=pthread_create(&thread_one,NULL,thread_func,NULL); if (res != 0) { perror("线程创建失败!"); exit(EXIT_FAILURE); } printf("输入一些字符,以'EOF'结束\n"); while(strncmp("EOF",work_area,3) != 0) { fgets(work_area,WORK_SIZE,stdin); sem_post(&bin_sem); } printf("\n等待线程结束...\n"); res=pthread_join(thread_one,&thread_result); if (res != 0) { perror("等待线程结束失败!"); exit(EXIT_FAILURE); } printf("线程结束!\n"); sem_destroy(&bin_sem); exit(EXIT_SUCCESS); } void * thread_func (void *arg) { sem_wait(&bin_sem); /*bin_sem的初始值为0,此处就是等待其值不为0*/ while(strncmp("EOF",work_area,3) != 0) { printf("你输入了%d个字节的文本\n",strlen(work_area)-1); sem_wait(&bin_sem); } pthread_exit(NULL); }
