作为多任务实现的一种机制,多线程应用得非常广泛,相对于多进程,多线程不仅运行效率高,而且还可以提高系统资源的使用效率。虽然网上关于多线程的讲解已经有一大堆,但出于学习的心态,有必要在这里做一下笔记。
一、多线程编程常用函数
1. int pthread_create(pthread_t * thread,const pthread_attr_t * attr,void * (*start_routine)(void *), void *arg);
作用:创建一个新线程
参数:
thread:线程ID
attr:线程属性(包括调度策略,调度参数,堆栈地址,堆栈大小等)。一般设置为NULL,即采用系统默认属性
void * (*start_routine):线程函数指针
*arg:线程函数参数的指针
返回值:
0:表示创建成功
其他:表示创建失败失败
2. int pthread_join(pthread_t th, void **thread_return);
作用:等待其他线程终止
参数:
th:需要等待的线程的ID
thread_return:所等待的线程的返回值
返回值:
0:表示成功
其他:表示失败
3. void pthread_exit(void *retval);
作用:终止当前线程
参数:
retval:线程的返回值
4. int pthread_mutex_lock(pthread_mutex_t *mutex);
作用:上锁,如果锁不可用则会阻塞当前线程直到锁可用
参数:
mutex:互斥变量
5. int pthread_mutex_unlock(pthread_mutex_t *mutex);
作用:与pthread_mutex_lock()相反6. pthread_t pthread_self(void);
作用:返回当前线程ID
返回值:
当前线程ID
7. int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
作用:解锁mutex,等待条件变量cond被发出信号
参数:
cond:条件变量
mutex:互斥锁对象
在调用此函数之前要先获得互斥锁,调用此函数时会自动释放互斥锁以防止死锁,这就是为什么此函数与互斥锁联系在一起的原因。另外此函数调用成功后当前线程会被挂起并放弃CPU,因此在等待的过程中是不会占用CPU资源的,当条件满足(被唤醒)时会重新上锁。
8. int pthread_cond_signal(pthread_cond_t *cond);
作用:重新开始(唤醒)正在等待条件变量cond的线程
参数:
cond:条件变量
二、实例
要求:在主线程里创建两个子线程,其中一个子线程输出1,3,5,7,9,另一个子线程输出2,4,6,8,10,输出的顺序是1,2,3,4,5,6,7,8,9,10。两个子线程都退出后主线程才退出。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 6 //初始化互斥锁 7 pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; 8 //初始化条件变量 9 pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER; 10 //初始化计数变量 11 int num = 1; 12 13 //线程1的线程函数 14 void *thread1(void *arg) 15 { 16 while(1) 17 { 18 //上锁 19 pthread_mutex_lock( &count_mutex ); 20 //如果num是奇数 21 if(num%2) 22 { 23 //输出当前num的值 24 printf("thread1 create: %d\n",num); 25 num++; 26 } 27 else 28 //解锁,等待 29 pthread_cond_wait( &condition_var, &count_mutex ); 30 //解锁 31 pthread_mutex_unlock( &count_mutex ); 32 if(num > 10) 33 return NULL; 34 } 35 36 } 37 38 //线程2的线程函数 39 void *thread2(void *arg) 40 { 41 while(1) 42 { 43 //上锁 44 pthread_mutex_lock( &count_mutex ); 45 //如果num是偶数 46 if(!(num%2)) 47 { 48 //输出当前num的值 49 printf("thread2 create: %d\n",num); 50 num++; 51 } 52 else 53 //唤醒正在等待的线程 54 pthread_cond_signal( &condition_var ); 55 56 //解锁 57 pthread_mutex_unlock( &count_mutex ); 58 if(num > 10) 59 { 60 //最后再唤醒一次以防止死锁 61 pthread_cond_signal( &condition_var ); 62 return NULL; 63 } 64 } 65 66 } 67 68 69 int main() 70 { 71 pthread_t t1,t2; 72 int ret; 73 74 //创建线程1 75 ret = pthread_create(&t1,NULL,thread1,NULL); 76 if(ret != 0) 77 { 78 printf("pthread_create 1 failed!\n"); 79 } 80 81 //创建线程2 82 ret = pthread_create(&t2,NULL,thread2,NULL); 83 if(ret != 0) 84 { 85 printf("pthread_create 2 failed!\n"); 86 } 87 88 //等待线程1结束 89 ret = pthread_join(t1,NULL); 90 if(ret != 0) 91 { 92 printf("pthread_join 1 failed!\n"); 93 } 94 95 //等待线程2结束 96 ret = pthread_join(t2,NULL); 97 if(ret != 0) 98 { 99 printf("pthread_join 2 failed!\n"); 100 } 101 102 return 0; 103 }
编译后运行,结果如下: