Last active
February 19, 2018 11:35
-
-
Save corvofeng/a314f6bd004db9162d5a9154d1dd7adc to your computer and use it in GitHub Desktop.
信号量使用的测试程序
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 测试环境: | |
* Archlinux 4.15.3-2 | |
* GCC 7.3.0 | |
* | |
* g++ -std=c++11 -g -pthread con_test.cpp | |
* | |
* 原文链接: https://corvo.myseu.cn/2018/02/17/2018-02-17-Spurious-Wakeup/ | |
*/ | |
#include <iostream> | |
#include <vector> | |
#include <map> | |
#include <pthread.h> | |
#include <unistd.h> | |
using namespace std; | |
class Lock | |
{ | |
public: | |
explicit Lock(pthread_mutex_t *mx) : mutex(mx) | |
{ | |
int err = pthread_mutex_lock(mutex); | |
printf("[LOCKER]: lock %d\n", err); | |
} | |
~Lock() | |
{ | |
int err = pthread_mutex_unlock(mutex); | |
printf("[LOCKER]: unlock %d\n", err); | |
mutex = nullptr; | |
} | |
private: | |
Lock(const Lock &l); | |
pthread_mutex_t *mutex; | |
}; | |
class Server | |
{ | |
public: | |
Server() | |
{ | |
isDel = true; | |
pthread_mutex_init(&delMtx, nullptr); | |
pthread_cond_init(&delCond, nullptr); | |
} | |
~Server() | |
{ | |
pthread_mutex_destroy(&delMtx); | |
pthread_cond_destroy(&delCond); | |
} | |
vector<int> forDel; | |
pthread_mutex_t delMtx; | |
pthread_cond_t delCond; | |
bool isDel; | |
}; | |
void *t0(void *args) | |
{ | |
Server *s = (Server *)args; | |
while (1) | |
{ | |
{ | |
Lock l(&s->delMtx); | |
if (!s->forDel.empty()) | |
{ | |
vector<int> rmVec; | |
swap(rmVec, s->forDel); | |
/** 遍历rmVec, 进行删除 */ | |
for (int i = 0; i < rmVec.size(); i++) | |
{ | |
} | |
printf("[0]: Notify the cond\n"); | |
s->isDel = true; | |
pthread_cond_signal(&s->delCond); /** 解除休眠状态 */ | |
} | |
else | |
{ | |
printf("[0]: No need to clean\n"); | |
} | |
} | |
printf("[0]: Do other job\n"); | |
sleep(10); // do other job. | |
} | |
return nullptr; | |
} | |
void *t1(void *args) | |
{ | |
Server *s = (Server *)args; | |
while (1) | |
{ | |
printf("[1]: Start Clean\n"); | |
vector<int> rmVec; | |
int a = rand() % 1500; | |
for (int i = 0; i < a; i++) | |
{ | |
rmVec.push_back(i); | |
} | |
// sleep(3); | |
if (!rmVec.empty()) | |
{ | |
Lock l(&s->delMtx); | |
swap(s->forDel, rmVec); | |
printf("[1]: check out %d \n", s->forDel.size()); | |
s->isDel = false; | |
while(!s->isDel) { | |
pthread_cond_wait(&s->delCond, &s->delMtx); /** 此时期望的行为: 进程进入休眠状态 */ | |
if(!s->isDel) { | |
printf("[1][ERROR]: need be cleaned\n"); | |
} | |
} | |
printf("[1]: clean over\n\n"); | |
} | |
} | |
return nullptr; | |
} | |
int main() | |
{ | |
Server s; | |
pthread_t p[2]; | |
int err; | |
err = pthread_create(&p[0], NULL, t0, &s); | |
err = pthread_create(&p[1], NULL, t1, &s); | |
pthread_join(p[0], nullptr); | |
pthread_join(p[1], nullptr); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment