├── README.md ├── philosopher_eat.cpp ├── producer.cpp └── read_write.cpp /README.md: -------------------------------------------------------------------------------- 1 | # MultiThreadLearning 2 | #经典多线程同步问题,分别是哲学家吃饭、读者写者、消费者生产者模型 3 | #采用C++11的多线程库,linux和window下都可以运行 4 | g++ read_write.cpp -o read_write -pthread -g 5 | 6 | 7 | -------------------------------------------------------------------------------- /philosopher_eat.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class semaphore 9 | { 10 | private: 11 | mutex mtx; 12 | condition_variable cv; 13 | int count; 14 | public: 15 | semaphore(int value = 1):count(value) {} 16 | 17 | void wait() 18 | { 19 | unique_lock lck(mtx); 20 | if(--count < 0)cv.wait(lck); 21 | } 22 | 23 | void signal() 24 | { 25 | unique_lock lck(mtx); 26 | if(++count <= 0) 27 | cv.notify_one(); 28 | } 29 | }; 30 | 31 | 32 | semaphore sem[5]; 33 | 34 | mutex mt; 35 | 36 | void pid(int id) 37 | { 38 | int left = (id+6)%5; 39 | int right = (id+4)%5; 40 | while(true) 41 | { 42 | unique_lock lck(mt); 43 | sem[left].wait(); 44 | sem[right].wait(); 45 | lck.unlock(); 46 | this_thread::sleep_for(chrono::milliseconds(1000)); 47 | cout << "Philosopher " << id << " eat \n"; 48 | sem[left].signal(); 49 | sem[right].signal(); 50 | } 51 | } 52 | 53 | int main() 54 | { 55 | thread ths[5]; 56 | for(int i = 0; i < 5; i++) 57 | { 58 | ths[i] = thread(pid,i+1); 59 | } 60 | 61 | for(int i = 0; i < 5; i++) 62 | { 63 | ths[i].join(); 64 | } 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /producer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | const int MAX = 20; 9 | mutex mtx; 10 | condition_variable pro,com; //生产者消费者条件变量 11 | 12 | queue q; 13 | 14 | void consumer() //消费者线程的入口 15 | { 16 | while(true) 17 | { 18 | this_thread::sleep_for(chrono::milliseconds(1000)); 19 | 20 | unique_lock lck(mtx); 21 | com.wait(lck, []{return q.size() != 0; }); 22 | 23 | cout << "comsumer " << this_thread::get_id() << ":"; 24 | q.pop(); 25 | cout << q.size() << "\n"; 26 | 27 | pro.notify_all(); 28 | } 29 | } 30 | 31 | void producer(int id) //生产者入口 32 | { 33 | while(true) 34 | { 35 | this_thread::sleep_for(chrono::milliseconds(900)); //生产者比消费者快 36 | unique_lock lck(mtx); 37 | pro.wait(lck,[]{return q.size() < MAX;}); //如果小于MAX就进入,否则不能进入 38 | 39 | cout << "->prodcer " << this_thread::get_id() << ":"; 40 | q.push(id); 41 | cout << q.size() << endl; 42 | 43 | com.notify_all(); 44 | } 45 | } 46 | 47 | int main() 48 | { 49 | thread consumers[2],producers[2]; 50 | 51 | for(int i = 0; i < 2; i++) 52 | { 53 | //创建两个消费者和生产者 54 | producers[i] = thread(producer, i + 1); 55 | consumers[i] = thread(consumer); 56 | } 57 | 58 | for(int i = 0; i < 2; ++i) 59 | { 60 | producers[i].join(); 61 | consumers[i].join(); 62 | } 63 | system("pasue"); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /read_write.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | //先实现一个信号量的类 10 | class semaphore 11 | { 12 | public: 13 | semaphore(int value = 1) :counts(value){} 14 | 15 | void wait() 16 | { 17 | unique_lock lck(mtxs); 18 | if(--counts < 0) 19 | cv.wait(lck); 20 | } 21 | 22 | void signal() 23 | { 24 | unique_lock lck(mtxs); 25 | if(++counts <= 0) 26 | cv.notify_one(); 27 | } 28 | private: 29 | int counts; 30 | mutex mtxs; 31 | condition_variable cv; 32 | }; 33 | //读者与读者不互斥,写者与写者与读者互斥 34 | //读者与写者互斥 35 | int count; //当前读者的数量 36 | 37 | 38 | mutex mtx; //用于保证读者与写者的互斥 39 | semaphore sm; //保证读者写者的互斥 40 | 41 | 42 | void write(int i) 43 | { 44 | while(true) 45 | { 46 | sm.wait(); 47 | cout << "writer " << i << " start writing " << endl; 48 | cout << "writer " << i << " end writing " << endl; 49 | sm.signal(); 50 | } 51 | } 52 | 53 | void reader(int i) 54 | { 55 | while(true) 56 | { 57 | mtx.lock(); 58 | if(count == 0) sm.wait(); 59 | ++count; 60 | mtx.unlock(); 61 | cout << "reader " << i << " start read " << endl; 62 | cout << "reader " << i << " end read " << endl; 63 | mtx.lock(); 64 | --count; 65 | if(count == 0) sm.signal(); 66 | mtx.unlock(); 67 | } 68 | } 69 | 70 | int main() 71 | { 72 | thread ths[8]; 73 | for(int i = 0; i < 2; i++) 74 | { 75 | ths[i] = thread(write,i); 76 | } 77 | for(int i = 2; i < 8; i++) 78 | { 79 | ths[i] = thread(reader,i); 80 | } 81 | 82 | for(int i = 0; i < 8; i++) 83 | ths[i].join(); 84 | return 0; 85 | } 86 | 87 | --------------------------------------------------------------------------------