线程,有时被称为轻量进程,是程序执行的最小单元。
一、C++11线程 1 2 3 4 5 6 7 8 9 #include <thread> void task (int i) { cout << "task:" << i << endl ; } thread t1 (task,100 ) ;t1.join();
二、POSIX线程 POSIX 可移植操作系统接口,标准定义了操作系统应该为应用程序提供的接口标准
1 2 3 4 5 6 7 8 9 10 11 #include <pthread.h> void *pthreadTask (void * args) { int * i = static_cast <int *>(args); cout << "posix线程:" << *i << endl ; return 0 ; } pthread_t pid;int pi = 100 ;pthread_create(&pid, 0 , pthreadTask, &pi); pthread_join(pid,0 );
1. 线程属性 线程具有属性,用 pthread_attr_t
表示
1 2 3 4 pthread_attr_t attr;pthread_attr_init(&attr); pthread_attr_destroy(&attr);
分离线程 线程创建默认是非分离的,当pthread_join()
函数返回时,创建的线程终止,释放自己占用的系统资源
分离线程不能被其他线程等待,pthread_join()
无效,线程自己玩自己的。
1 2 3 4 pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
调度策略与优先级 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 pthread_attr_setschedpolicy(&attr, SCHED_FIFO); int max = sched_get_priority_max(SCHED_FIFO);int min = sched_get_priority_min(SCHED_FIFO);sched_param param; param.sched_priority = max; pthread_attr_setschedparam(&attr, ¶m);
1. 线程同步 多线程同时读写同一份共享资源的时候,可能会引起冲突。需要引入线程“同步”机制,即各位线程之间有序地对共享资源进行操作。
以下是会出现问题的写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <pthread.h> using namespace std ;queue <int > q;void *pop (void * args) { if (!q.empty()) { printf ("取出数据:%d\n" , q.front()); q.pop(); } else { printf ("无数据\n" ); } return 0 ; } int main () { for (size_t i = 0 ; i < 5 ; i++) { q.push(i); } pthread_t pid[10 ]; for (size_t i = 0 ; i < 10 ; i++) { pthread_create(&pid[i], 0 , pop, &q); } system("pause" ); return 0 ; }
加入互斥锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 queue <int > q;pthread_mutex_t mutex;void *pop (void * args) { pthread_mutex_lock(&mutex); if (!q.empty()) { printf ("取出数据:%d\n" , q.front()); q.pop(); } else { printf ("无数据\n" ); } pthread_mutex_unlock(&mutex); return 0 ; } int main () { pthread_mutex_init(&mutex, 0 ); for (size_t i = 0 ; i < 5 ; i++) { q.push(i); } pthread_t pid[10 ]; for (size_t i = 0 ; i < 10 ; i++) { pthread_create(&pid[i], 0 , pop, &q); } for (size_t i = 0 ; i < 10 ; i++) { pthread_join(pid[i], 0 ); } pthread_mutex_destroy(&mutex); system("pause" ); return 0 ; }
2. 条件变量 条件变量是线程间进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使”条件成立”,从而唤醒挂起线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 template <class T >class SafeQueue {public : SafeQueue() { pthread_mutex_init(&mutex,0 ); } ~SafeQueue() { pthread_mutex_destory(&mutex); } void enqueue (T t) { pthread_mutex_lock(&mutex); q.push(t); pthread_mutex_unlock(&mutex); } int dequeue (T& t) { pthread_mutex_lock(&mutex); if (!q.empty()) { t = q.front(); q.pop(); pthread_mutex_unlock(&mutex); return 1 ; } pthread_mutex_unlock(&mutex); return 0 ; } private : queue <T> q; pthread_mutex_t mutex; };
上面的模板类存放数据T,并使用互斥锁保证对queue的操作是线程安全的。这就是一个生产/消费模式。
如果在取出数据的时候,queue为空,则一直等待,直到下一次enqueue加入数据。
这就是一个典型的生产/消费模式, 加入条件变量使 “dequeue” 挂起,直到由其他地方唤醒
下面是使用条件变量实现
通过使用cond条件来 唤醒等待中的线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #pragma once #include <queue> using namespace std ;template <class T >class SafeQueue {public : SafeQueue() { pthread_mutex_init(&mutex,0 ); pthread_cond_init(&cond, 0 ); } ~SafeQueue() { pthread_mutex_destory(&mutex); pthread_cond_destory(&cond); } void enqueue (T t) { pthread_mutex_lock(&mutex); q.push(t); pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mutex); } int dequeue (T& t) { pthread_mutex_lock(&mutex); while (q.empty()) { pthread_cond_wait(&cond, &mutex); } t = q.front(); q.pop(); pthread_mutex_unlock(&mutex); return 1 ; } private : queue <T> q; pthread_mutex_t mutex; pthread_cond_t cond; };
代码 https://github.com/ddssingsong/AnyNdk