thead
#include <iostream>
#include <thread>
void runAction(int number) {
for (int i = 0; i < 500; ++i) {
std::cout << "runAction: " << number << std::endl;
}
}
int main() {
std::thread thead1(runAction, 10);
thead1.join(); // 等执行完,再执行下面的代码
std::cout << "game over!" << std::endl;
return 0;
}
pthreads
cygwin环境
该环境有pthreads文件,否则无法使用 !
可以参考博文:clion以及cygwin的安装与配置
分离线程 & 非分离线程的区别?
分离线程:各个线程各自运行,没有协作,例如main函数结束,全部结束,不会等待异步线程【多线程场景下】
非分离线程:线程协作,例如main函数等待异步线程执行完再执行后面的代码【协作 顺序执行的场景】
pthread_join
#include <iostream>
#include <pthread.h> // cygwin 有pthreads文件
#include <unistd.h>
// 异步线程
void * customTask(void * pVoid) {
int * number = static_cast<int *>(pVoid);
std::cout << "pthread:" << *number << std::endl;
sleep(5);
return 0; // 必须 return 返回
}
int main() {
int number = 100;
// 每个线程的线程ID
pthread_t pthreadID;
pthread_create(&pthreadID, 0, customTask, &number);
// 等异步线程执行完成再执行后续的代码
pthread_join(pthreadID, 0);
std::cout << "game over!" << std::endl;
return 0;
}
互斥锁
#include <iostream>
#include <pthread.h> // cygwin 有pthreads文件
#include <unistd.h>
#include <queue>
// 定义互斥锁 不能有野指针
pthread_mutex_t mutex;
// 定义Queue
std::queue<int> queueData;
// 异步线程
void * customTask(void * pVoid) {
// 加锁
pthread_mutex_lock(&mutex);
int * number = static_cast<int *>(pVoid);
if (!queueData.empty()) {
std::cout << "pthread:" << *number << " queue:" << queueData.front() << std::endl;
queueData.pop();
} else {
std::cout << "pthread:" << *number << " queue is empty!" << std::endl;
}
sleep(2);
// 解锁
pthread_mutex_unlock(&mutex);
return 0; // 必须 return 返回
}
int main() {
// 初始化 互斥锁
pthread_mutex_init(&mutex, NULL);
for (int i = 10000; i < 10005; ++i) {
queueData.push(i);
}
// 定义10个线程
pthread_t pthreadIDArray[10];
for (int i = 0; i < 10; ++i) {
pthread_create(&pthreadIDArray[i], 0, customTask, &i);
}
// main函数等待异步线程 5s
sleep(5);
// 销毁 互斥锁
pthread_mutex_destroy(&mutex);
std::cout << "game over!" << std::endl;
return 0;
}
生产者 & 消费者
my_queue.h
#ifndef MYCPPTEST_MY_QUEUE_H
#define MYCPPTEST_MY_QUEUE_H
#endif //MYCPPTEST_MY_QUEUE_H
#pragma once
#include <iostream>
#include <pthread.h> // cygwin 有pthreads文件
#include <unistd.h>
#include <queue>
template<typename T>
class MyQueueClass {
private:
std::queue<T> queue;
pthread_mutex_t mutex; // 互斥锁
pthread_cond_t cond; // 条件变量 不能有野指针
public:
MyQueueClass() {
// 初始化 互斥锁
pthread_mutex_init(&mutex, 0);
// 初始化 条件变量
pthread_cond_init(&cond, 0);
}
~MyQueueClass() {
// 回收 互斥锁
pthread_mutex_destroy(&mutex);
// 回收 条件变量
pthread_cond_destroy(&cond);
}
void addData(T t) {
// 加锁
pthread_mutex_lock(&mutex);
queue.push(t);
std::cout << "add one, broadcast... " << std::endl;
// 广播
pthread_cond_broadcast(&cond);
// 解锁
pthread_mutex_unlock(&mutex);
}
// 引用的方式获取元素
void deleteData(T & t) {
// 加锁
pthread_mutex_lock(&mutex);
while (queue.empty()) {
std::cout << "queue is empty ... " << std::endl;
// wait
pthread_cond_wait(&cond, &mutex);
}
// 唤醒了之后
t = queue.front();
queue.pop();
// 解锁
pthread_mutex_unlock(&mutex);
}
};
main.cpp
#include <iostream>
#include "my_queue.h"
MyQueueClass<int> myQueueClass;
// 消费
void * deleteMethod(void *) {
while (true) {
int value;
myQueueClass.deleteData(value);
std::cout << "delete data: " << value << std::endl;
if (value == -1){
std::cout << "delete game over!" << std::endl;
break;
}
}
return 0; // 必须 return 返回
}
// 生产
void * addMethod(void *) {
while (true) {
int value;
std::cout << "please input number: ";
std::cin >> value;
if (value == -1) {
myQueueClass.addData(value);
std::cout << "add game over!" << std::endl;
break;
}
myQueueClass.addData(value);
sleep(1);
}
return 0; // 必须 return 返回
}
int main() {
pthread_t pthreadDelete;
pthread_create(&pthreadDelete, 0, deleteMethod, 0);
pthread_t pthreadAdd;
pthread_create(&pthreadAdd, 0, addMethod, 0);
pthread_join(pthreadDelete, 0);
pthread_join(pthreadAdd, 0);
std::cout << "game over!" << std::endl;
return 0;
}