Skip to content

Instantly share code, notes, and snippets.

@corvofeng
Last active February 19, 2018 11:35
Show Gist options
  • Save corvofeng/a314f6bd004db9162d5a9154d1dd7adc to your computer and use it in GitHub Desktop.
Save corvofeng/a314f6bd004db9162d5a9154d1dd7adc to your computer and use it in GitHub Desktop.
信号量使用的测试程序
/**
* 测试环境:
* 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