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 33 34 35 36 37 38 39 40
| #include <iostream> #include <vector> using namespace std;
class Student { private: string info = "AAA";
public: string getInfo() { return this->info; }
public: string & getInfo_front() { return this->info; } };
int main() {
Student student;
student.getInfo() = "九阳神功"; string result = student.getInfo(); cout << "第一种情况:" << result << endl;
student.getInfo_front() = "三分归元气"; result = student.getInfo_front(); cout << "第二种情况:" << result << endl; }
|
2. thread
thread是C++ 11引入的一个线程类,主要也是封装pthread类,用起来更简单,但是阉割了部分功能,日常开发中主要还是使用pthread。
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
| #include <iostream> #include <thread> #include <unistd.h>
using namespace std;
void runAction(int number) { for (int i = 0; i < 10; ++i) { cout << "runAction:" << number << endl; sleep(1); } }
int main() {
thread thread2(runAction, 100); thread2.join(); cout << "main弹栈了" << endl;
return 0; }
|
3. pthread用法
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
| #include <iostream> #include <pthread.h> // Cygwin 有 pthreads支持 using namespace std;
void * customPthreadTask(void * pVoid) { int * number = static_cast<int *>(pVoid); cout << "异步线程执行了:" << *number << endl;
return 0; }
int main() { int number = 9527;
pthread_t pthreadID;
pthread_create(&pthreadID, 0, customPthreadTask, &number);
return 0; }
|
4. pthread的三种状态
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
|
#include <iostream> #include <pthread.h> // Derry Cygwin 有 pthreads支持 #include <unistd.h>
using namespace std;
void * runTask(void * pVoid) { int number = *static_cast<int *>(pVoid); cout << "异步线程执行了:" << number << endl;
for (int i = 0; i < 10; ++i) { cout << "run:" << i << endl; sleep(1); }
return 0; }
int main() { int number = 999;
pthread_t pthreadID; pthread_create(&pthreadID, 0, runTask, &number);
pthread_join(pthreadID, 0);
cout << "main函数即将弹栈..." << endl; return 0; }
|
5. 分离线程与非分离线程区别
- 分离线程: 各个线程都是自己运行自己的,老死不相往来,例如:main函数结束,全部结束,不会等待异步线程 【多线程独立计算情况下场景】
- 非分离线程: 线程有协作的能力,例如:main函数线程会等待 异步线程执行完成后,我再执行 后面main函数的代码【协作,顺序执行 场景】
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
| #include <iostream> #include <pthread.h> // Derry Cygwin 有 pthreads支持 #include <unistd.h>
using namespace std;
void * runTask(void * pVoid) { int number = *static_cast<int *>(pVoid); cout << "异步线程执行了:" << number << endl;
for (int i = 0; i < 10; ++i) { cout << "run:" << i << endl; sleep(1); } return 0; }
int main() { int number = 999;
pthread_t pthreadID; pthread_create(&pthreadID, 0, runTask, &number);
pthread_join(pthreadID, 0);
cout << "main函数即将弹栈..." << endl; return 0; }
|
6. 互斥锁
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <iostream> #include <pthread.h> #include <queue> #include <unistd.h> // sleep(秒)
using namespace std;
queue<int> queueData;
pthread_mutex_t mutex;
void *task(void *pVoid) {
pthread_mutex_lock(&mutex);
cout << "异步线程-当前线程的标记是:" << *static_cast<int *>(pVoid) << "异步线程" << endl;
if (!queueData.empty()) { printf("异步线程-获取队列的数据:%d\n", queueData.front()); queueData.pop(); } else { printf("异步线程-队列中没有数据了\n"); }
sleep(0.2);
pthread_mutex_unlock(&mutex);
return 0; }
int main() { pthread_mutex_init(&mutex, NULL);
for (int i = 10001; i < 10011; ++i) { queueData.push(i); }
pthread_t pthreadIDArray[10]; for (int i = 0; i < 10; ++i) { pthread_create(&pthreadIDArray[i], 0, task, &i);
}
sleep(12);
pthread_mutex_destroy(&mutex); cout << "main函数即将弹栈..." << endl;
return 0; }
|
7. 多线程通知机制实现生产者消费者模型
建立一个队列,在get(),set()方法中使用互斥锁对队列存元素和元素进行加锁。
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #ifndef CPPCLIONPROJECT_SAFE_QUEUE_TOO_H #define CPPCLIONPROJECT_SAFE_QUEUE_TOO_H
#endif
#pragma once
#include <iostream> #include <string> #include <pthread.h> #include <string> #include <queue>
using namespace std;
template<typename T>
class SafeQueueClass { private: queue<T> queue; pthread_mutex_t mutex; pthread_cond_t cond;
public: SafeQueueClass() { pthread_mutex_init(&mutex, 0);
pthread_cond_init(&cond, 0); } ~SafeQueueClass() { pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond); }
void add(T t) { pthread_mutex_lock(&mutex);
queue.push(t);
pthread_cond_broadcast(&cond);
cout << "add queue.push 我已经notifyAll所有等待线程了" << endl;
pthread_mutex_unlock(&mutex); }
void get(T & t) { pthread_mutex_lock(&mutex);
while (queue.empty()) { cout << "get empty 我已经乖乖等待中.." << endl; pthread_cond_wait(&cond, &mutex); }
t = queue.front(); queue.pop();
pthread_mutex_unlock(&mutex); } };
|
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #pragma once
#include <iostream>
#include "safe_queue_too.h" using namespace std; SafeQueueClass<int> sq;
void * getMethod(void *) { while (true) { printf("getMethod\n");
int value; sq.get(value); printf("消费者get 得到的数据:%d\n", value);
if (-1 == value) { printf("消费者get 全部执行完毕\n"); break; } } return 0; }
void * setMethod(void *) { while (true) { printf("setMethod\n");
int value; printf("请输入你要生成的信息:\n"); cin >> value;
if (-1 == value) { sq.add(value); printf("消费者get 全部执行完毕\n"); break; }
sq.add(value); } return 0; }
int main() { pthread_t pthreadGet; pthread_create(&pthreadGet, 0, getMethod, 0);
pthread_t pthreadSet; pthread_create(&pthreadSet, 0, setMethod, 0);
pthread_join(pthreadGet, 0);
pthread_join(pthreadSet, 0);
return 0; }
|
版权声明: 此文章版权归Jack Ou所有,如有转载,请註明来自原作者