编译时要链接上pthread库, gcc thread.c -o thread -l pthread
#include
#include
#include void *thread_entry(void*arg)//线程运行的函数
{while(1){printf("i am child thread:%s\n",arg);sleep(1);}return NULL;
}
int main()
{//int pthread_create(pthread_t * tid, pthread_attr_t * attr, void* (*routine)(void*), void *agr)pthread_t tid;char* arg="你好!";int ret=pthread_create(&tid,NULL,thread_entry,(void*)arg);if(ret!=0){printf("pthread create error!\n");return -1;}//线程一旦创建成功了,创建成出来的线程调度的是传入的线程入口函数,while(1){printf("i am a main thread\n");sleep(1);}return 0;
}
带信息头的查看线程信息
ps -efL | head -n 1 && ps -efL|grep thread
pthread_exit
pthread_cancel
更详细的线程信息
ps -efL -l | head -n 1 && ps -efL -l | grep thread
等待:等待指定线程退出,获取退出返回值,回收未被完全释放的资源
在线程中,有个分离属性,默认值是joinable状态,表示线程退出后不会自动释放所有资源,需要被其他线程等待
pthread_join
等待线程指定的线程终止
分离:将线程的分离属性社会为detach,表示线程退出后自动释放所有资源,则这种线程退出后不需要被等待(不关心其返回值时采用)
pthread_detach
分离一个线程
Product_and_consumer.cpp
#include
using namespace std;
#include
#include
template
class BlockQueue{public:BlockQueue(int capacity):_capacity(capacity){pthread_mutex_init(&_mutex,NULL);pthread_cond_init(&_cond_pro,NULL);pthread_cond_init(&_cond_con,NULL);};~BlockQueue(){pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_cond_pro);pthread_cond_destroy(&_cond_con);};bool Push(const T & data){//push是生产者线程运行的pthread_mutex_lock(&_mutex);while(_capacity==_q.size()){//容量达到队列上限就要停止生产,唤醒消费者线程pthread_cond_wait(&_cond_pro,&_mutex);//阻塞生产者进程}_q.push(data);cout<<"+++++"<pthread_mutex_lock(&_mutex);while(_q.empty()){pthread_cond_wait(&_cond_con,&_mutex);}*data=_q.front();_q.pop();cout<<"-----"< _q;int _capacity;pthread_mutex_t _mutex;//互斥锁pthread_cond_t _cond_pro;//生产者同步变量pthread_cond_t _cond_con;//消费者:
};#define MAX_USER 4
void * consumer(void* arg)
{BlockQueue *q=(BlockQueue *)arg;while(1){int data;q->Pop(&data);}return NULL;
}void * productor(void* arg)
{BlockQueue *q = (BlockQueue *)arg;int data=0;while(1){q->Push(data++);}return NULL;
}int main()
{BlockQueue q(5);pthread_t cond_tid[MAX_USER],pro_tid[MAX_USER];int ret;for(int i=0;iret=pthread_create(&cond_tid[i],NULL,consumer,(void*)&q);if(ret!=0){std::cout<<"pthread_create error\n";return -1;}ret=pthread_create(&pro_tid[i],NULL,productor,(void*)&q);if(ret!=0){std::cout<<"pthread_create error\n";return -1;}}for(int i=0;ipthread_join(cond_tid[i],NULL);pthread_join(pro_tid[i],NULL);}return 0;
}
#include
#include
#include
#includetemplate
class RingQueue{private:std::vector _arr;int _read_step;int _write_step;int _capacity;sem_t _sem_data;sem_t _sem_idle;sem_t _sem_lock;public:RingQueue(int capacity):_capacity(capacity),_arr(capacity),_read_step(0),_write_step(0){sem_init(&_sem_idle,0,capacity);sem_init(&_sem_data,0,0);sem_init(&_sem_lock,0,1);}~RingQueue(){sem_destroy(&_sem_idle);sem_destroy(&_sem_data);sem_destroy(&_sem_lock);}bool Push(const T& data){sem_wait(&_sem_lock);sem_wait(&_sem_idle);_arr[_write_step]=data;_write_step=(_write_step+1)%_capacity;sem_post(&_sem_data);sem_post(&_sem_lock);return true;}bool Pop(T* data){sem_wait(&_sem_lock);sem_wait(&_sem_data);*data=_arr(_read_step+1)%_capacity;sem_post(&_sem_idle);sem_post(&_sem_lock);return true;}};
template//线程池只是一个执行流的池子,本身并不知道一个任务该如何处理,因此设计一个任务类
class ThreadTask{private:T _data;//处理的数据std::function _handler;//任务处理方法public:void start(){ return _handler(_data) };
};
class ThreadPool{private:int _max_thread;//线程的数量BlockQueue< ThreadTask > _queue;public:ThreadPool(){//完成线程的创建}bool Push(ThreadTask & task);
};
//
// Created by AIERXUAN on 2023/3/11.
//
#include
#include
#include
#include
#include
#include#define MAX_QUEUE 5;using namespace std;template
class BlockQueue {
private:queue _q;int _capacity;//队列容量限制pthread_mutex_t _mutex;pthread_cond_t _cond_pro;pthread_cond_t _cond_con;
public:BlockQueue(int capacity):_capacity(capacity){pthread_mutex_init(&_mutex, nullptr);pthread_cond_init(&_cond_pro, nullptr);pthread_cond_init(&_cond_con, nullptr);}~BlockQueue() {pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_cond_pro);pthread_cond_destroy(&_cond_con);}void Push(const T &data) {//生产者,队满停止生产pthread_mutex_lock(&_mutex);while (_capacity == _q.size()) {pthread_cond_wait(&_cond_pro, &_mutex);}_q.push(data);pthread_cond_signal(&_cond_con);pthread_mutex_unlock(&_mutex);}void Pop(T *data) {//出队操作,消费者,队不空才可以出队,队空阻塞唤醒生产者pthread_mutex_lock(&_mutex);while (_q.empty()) {pthread_cond_wait(&_cond_pro, &_mutex);}*data = _q.front();_q.pop();pthread_cond_signal(&_cond_pro);pthread_mutex_unlock(&_mutex);}
};template
class ThreadTask {public:using Handler = function;/*等价于 Handler = std::funtional ; 定义了一个函数类型*/ThreadTask() = default;ThreadTask(const T &data, Handler handler) : _data(data), _handler(std::move(handler)) {}void Start() {return _handler(_data);}private:T _data{};Handler _handler;
};template
class ThreadPool {
private:int _thread_max;BlockQueue> _queue;//线程安全的任务队列vector _tid;//保存所有线程的tid
private:static void *thread_entry(void *arg) {//循环从任务队列中取出任务调用的Start接口进行任务处理auto *pool = (ThreadPool *) arg;while (1) {ThreadTask task;pool->_queue.Pop(&task);//无效的静态成员函数中访问了非静态成员变量task.Start();}return nullptr;}public://完成创建指定数量的线程ThreadPool(int thread_max, int queue_max) : _thread_max(thread_max), _queue(queue_max) {int ret;pthread_t tid;for (int i = 0; i < thread_max; ++i) {ret = pthread_create(&tid, nullptr, thread_entry, this);if (ret != 0) {cout << "create thread failed!\n";exit(-1);}}}bool Push(ThreadTask &task) {//任务入队_queue.Push(task);return true;}
};void print_test(int data) {printf("%llu thread ,run data:%d\n",pthread_self(),data);sleep((data % 3) + 1);
}int main() {ThreadPool pool(5, 10);for (int i = 0; i < 10; ++i) {ThreadTask task(i, print_test);pool.Push((task));}sleep(10);return 0;
}
Ensure a class has only one instance and provide a global point of access to it.
确保类只有一个实例,并提供对它的全局访问点。
#include
#include using namespace std;//class Singleton {//饿汉模式
//private:
// string _data;
//private:
// static Singleton _eton;//静态成员
//
// Singleton() {//构造函数私有化,类外无法实例化对象,保证一个类只能实例化一个对象
// _data = “饿汉”;
// }
//
//public:
// string get_data() { return _data; }
//
// static Singleton *GetInstance() {
// return &_eton;
// }
//};
//
//Singleton Singleton::_eton;//静态变量在类外定义class Singleton {
private:string _data="懒汉";static Singleton *_eton;static std::mutex _mutex;
public:string get_data() { return _data; }static Singleton *GetInstance() {if (_eton == NULL)_mutex.lock();//保证实例化过程的线程安全问题,if (_eton == NULL) {_eton = new Singleton;}_mutex.unlock();return _eton;}
};Singleton *Singleton::_eton = nullptr;
std::mutex Singleton::_mutex;
int main() {Singleton *singleton = Singleton::GetInstance();std::cout << singleton->get_data() << std::endl;return 0;
}
替换掉每行首的所有空格及数字
VIM底行模式下
:1,$s/^\s*[0-9]\s//g
解释:1为起始行号,315为终止行号,在正则中代表行首,\s*代表若干个空格,可以没有,[0-9]*代表若干个数字,可以没有,即将\s*[0-9]\s替换为NOTHING。
或者:
:%s/^…//g