- 本文出自<svtter.github.io>
使用pthread实现经典问题:生产者消费者
关于semaphore的相关信息就不再贴出来了。
编译的时候记得-pthread
选项。
/*============================================================================= # # Author: svtter - [email protected] # # QQ : 57180160 # # Last modified: 2014-10-03 20:35 # # Filename: producer_consumer.cc # # Description: # =============================================================================*/ #include <cstdio> #include <unistd.h> #include <semaphore.h> #include <pthread.h> #include <sys/types.h> #include <stdlib.h> #include <iostream> using namespace std; #define N 5 #define item int // P/V操作 void P(sem_t* sem) { if(sem_wait(sem)) perror("P error!"); } void V(sem_t* sem) { if(sem_post(sem)) perror("V error!"); } sem_t mutex; sem_t full; sem_t empty; item buffer[N]; int i = , j = -1; void init_sem() { sem_init(&mutex, , 1); sem_init(&full, , ); sem_init(&empty, , N); } void* producer(void *arg) { int product; while(1) { //生成随机数字 product = rand()%100; // cout << "producer running..." << endl; P(&empty); P(&mutex); buffer[i] = product; printf("producer produced %d @ %d pos\n", product, i); i=(i+1)%N; V(&mutex); V(&full); sleep(1); } } void* consumer(void *arg) { int product, temp; while(1) { // cout << "consumer running..." << endl; P(&full); P(&mutex); j = (j+1)%N; product = buffer[j]; V(&mutex); V(&empty); printf("Consumer consumed %d @ %d pos\n", product, j); sleep(3); } } int main() { //random num srand(time(NULL)); init_sem(); int error; pthread_t producer_t, consumer_t; error = pthread_create(&producer_t, NULL, producer, NULL); if(error != ) printf("error in create producer.\n"); else printf("create producer success!\n"); pthread_create(&consumer_t, NULL, consumer, NULL); if(error != ) printf("error in create consumer.\n"); else printf("create consumer success!\n"); pthread_join(producer_t, NULL); pthread_join(consumer_t, NULL); return ; }
运行结果

操作系统经典问题:哲学家就餐问题
mutex是c++11的新功能。记得添加C++11支持。(在运行结果中包含编译选项。)
#include <iostream> #include <mutex> #include <cstdio> #include <thread> #include <semaphore.h> using namespace std; #define THINK(i) printf("ph[%d] is thinking...\n", i) #define EAT(i) printf("ph[%d] eats.\n", i) void P(mutex &mt) { mt.lock(); } void V(mutex &mt) { mt.unlock(); } void P(sem_t* sem) { if(sem_wait(sem)) perror("P error!"); } void V(sem_t* sem) { if(sem_post(sem)) perror("V error!"); } // 加入unistd.h出现问题,似乎与thread的兼容性比较差,于是重写 void delay() { int sum=; for(int i = ; i < 10000000; i++) sum += i; } mutex fork[5]; sem_t room; void init() { sem_init(&room, , 4); } void philosopher (int i) { for(int j = ; j < 5; j++) { THINK(i); P(&room); P(fork[i]); P(fork[(i+1)%5]); EAT(i); V(&room); V(fork[i]); V(fork[(i+1)%5]); } } int main() { init(); thread t[] = { thread(philosopher, ), thread(philosopher, 1), thread(philosopher, 2), thread(philosopher, 3), thread(philosopher, 4), }; for(int k = ; k < 5; k++) t[k].join(); return ; }
运行结果

操作系统经典问题:读者写者问题
读者优先
- 使用了c++11的新特性thread
#include <iostream> #include <mutex> #include <thread> using namespace std; mutex mt, wsem; int readcount = ; #define READ(a) cout << a << " is reading..." << endl; #define FINISH(a) cout << a << " finished reading." << endl; #define WRITE cout << "writing..." << endl; void P(mutex &mt) { mt.lock(); } void V(mutex &mt) { mt.unlock(); } // 加入unistd.h出现问题,似乎与thread的兼容性比较差,于是重写 void delay() { int sum=; for(int i = ; i < 10000000; i++) sum += i } void read(string a) { for(int i = ; i < 3; i++) { P(mt); readcount++; if(readcount == 1) P(wsem); V(mt); READ(a); delay(); P(mt); readcount--; FINISH(a); if(readcount == ) V(wsem); V(mt); } } void write() { for(int i = ; i < 5; i++) { P(wsem); WRITE; delay(); V(wsem); } } int main() { thread reader1(read, "svtter"); thread reader2(read, "sr"); thread reader3(read, "yym"); thread reader4(read, "xiaoniu"); thread writer(write); reader1.join(); reader2.join(); reader3.join(); reader4.join(); writer.join(); return ; }
运行结果
由于可以同时阅读,所以读者reading输出可能出现少许问题。

写者优先
- 使rsem中只有一个读者在等待,保证了如果有写者,写者优先写
#include <iostream> #include <mutex> #include <thread> using namespace std; #define READ(a,i) cout << a << i<<" is reading..." << endl; #define FINR(a,i) cout << a << i<<" finished reading." << endl; #define WRITE(a,i) cout << a <<i<<" is writing..." << endl; #define FINW(a, i) cout << a <<i<<" finished writing..." << endl; void P(mutex &mt) { mt.lock(); } void V(mutex &mt) { mt.unlock(); } // 加入unistd.h出现问题,似乎与thread的兼容性比较差,于是重写 void delay() { int sum=; for(int i = ; i < 10000000; i++) sum += i; } mutex mr, wsem, rsem, mrc, mwc; int readcount = ; int writecount = ; void read(string a) { for(int i = ; i < 5; i++) { P(mr); P(rsem); P(mrc); readcount++; if(readcount == 1) P(wsem); V(mrc); V(rsem); V(mr); READ(a, i); P(mrc); FINR(a, i); readcount--; if(readcount == ) V(wsem); V(mrc); } } void write(string a) { for(int i = ; i < 3; i++) { P(mwc); writecount++; if(writecount == 1) P(rsem); V(mwc); P(wsem); WRITE(a, i); FINW(a, i); V(wsem); P(mwc); writecount--; if(writecount == ) V(rsem); V(mwc); } } int main() { thread reader1(read, "svtter"); thread writer1(write, "sr"); thread writer2(write, "zs"); thread writer3(write, "yym"); reader1.join(); writer1.join(); writer2.join(); writer3.join(); return ; }
运行结果
- 基本上结果就是写者写完,才会有读者阅读
