Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用sempaphore并调用wait()和signal()_C++_Multithreading_Semaphore - Fatal编程技术网

C++ 使用sempaphore并调用wait()和signal()

C++ 使用sempaphore并调用wait()和signal(),c++,multithreading,semaphore,C++,Multithreading,Semaphore,问题就在这里。洗手间一次可供男性或女性使用。如果男性或女性在特定时间在洗手间,异性不能进入洗手间,必须等待。一旦所有的雌性都出去了,雄性就可以进去了。所以,我的解决方案是: 我想使用信号量和互斥量在线程之间执行同步。我仍然不清楚如何实施它。 以下是我的想法: 创建互斥锁以锁定/解锁线程。锁定洗手间 创建一个信号灯来计算洗手间的人数。男女各一人 洗手间内的信号灯; 洗手间女厕所的信号灯; 排队等候的男性, 排队等候的女性, 首先,我检查什么是性别,然后我检查异性的符号是否大于1。如果没有,我就让他

问题就在这里。洗手间一次可供男性或女性使用。如果男性或女性在特定时间在洗手间,异性不能进入洗手间,必须等待。一旦所有的雌性都出去了,雄性就可以进去了。所以,我的解决方案是:

我想使用信号量和互斥量在线程之间执行同步。我仍然不清楚如何实施它。 以下是我的想法:

创建互斥锁以锁定/解锁线程。锁定洗手间 创建一个信号灯来计算洗手间的人数。男女各一人 洗手间内的信号灯; 洗手间女厕所的信号灯; 排队等候的男性, 排队等候的女性, 首先,我检查什么是性别,然后我检查异性的符号是否大于1。如果没有,我就让他们进洗手间。但是如果洗手间里已经有反对性行为的人,我需要让这个过程等待,然后让它进入睡眠状态

我该如何让这个过程进入睡眠状态?我已经找了一些例子,但仍然不知道如何做

使用wait和signal函数签名的示例将非常有用

创建一个信号灯来计算洗手间的人数。一 洗手间内的每个性别信号灯均为男性;洗手间女厕所的信号灯; 等待男性排队,等待女性排队

没什么意义。信号量值的目的是指示资源是否可用。如果该值为零,则资源不可用。如果大于零,则可用。因此,如果您设法通过使用资源来增加sem计数,那么信号量有什么用途呢

因此,首先,我检查性是什么过程,然后我检查 相反性别的符号大于1。如果不是,我就让他们 进入洗手间

不,不,不!你知道了,巴斯·阿克沃德。这强调了一点:信号量不是用来存储任意值的

您的各种计数等都是普通变量,而不是信号量,但是,您必须使用互斥量/信号量/条件变量(最有可能是:互斥量+条件变量)来控制对它们的访问


另外,我不知道你为什么认为跟踪有多少人在等待是有用或重要的。

这看起来很有趣,所以我写了一些代码。虽然还没有测试过,所以可能把事情搞砸了,但它足够清楚地证明了我的想法

typedef enum {
    none = -1,
    male = 0,
    female = 1
} sex_t;

class Human {
public:
    const sex_t id;
    Human(sex_t id_) : id(id_) {assert(id != none);}
};

class Restroom {
    tbb::spin_mutex     door_mutex;
    tbb::atomic<size_t> num_waiting;
    HANDLE              opposite_sex_can_enter;

    // these two variables need not be atomic, they're not accessed concurrently
    sex_t               current_occupying_sex;
    size_t              num_visitors;

public:
    Restroom() : current_occupying_sex(none), num_visitors(0) {
        num_waiting = 0;
        opposite_sex_can_enter = CreateEvent(0, TRUE, FALSE, 0);
    }

    void enter(const Human& h) {
        tbb::spin_mutex::scoped_lock lock(door_mutex);
        // this prevents any two humans trying to open the door (in any direction) at the same time :)
        if(current_occupying_sex == none) {
            // you're the first one in, so update the 'restroom id' and enter
            assert(num_visitors == 0 && num_waiting == 0);
            // if the knowledge of SetEvent has not propagated all the way yet and the same sex
            // person happens to walk into the restroom again, opposite sex people need to know
            // that they were slow and will need to wait again
            ResetEvent(opposite_sex_can_enter);
            current_occupying_sex = h.id;
            ++num_visitors;
        } else if(h.id == current_occupying_sex) {
            // you're not the first one in, but you're of the same sex, so you can just walk in
            assert(num_visitors > 0);
            ++num_visitors;
        } else {
            // you're not the first one in and you're of opposite sex, so you'll need to wait
            // first, let go of the door, you're not getting in :)
            lock.release();
            // then join the rest of the opposite sex people waiting
            ++num_waiting;
            WaitForSingleObject(opposite_sex_can_enter);
            --num_waiting;
            if(num_waiting == 0) {
                ResetEvent(opposite_sex_can_enter);
            }
            enter(h);
        }
    }

    void exit() {
        tbb::spin_mutex::scoped_lock lock(door_mutex);
        if(--num_visitors == 0) {
            current_occupying_sex = none;
            SetEvent(opposite_sex_can_enter);
            // fairness can be imposed here, meaning that if you're the last say, male
            // to walk out, you can check if females are waiting and switch the 
            // restroom sex id to female. The logic of enter() will change a little bit, but not radically.
        }
    }
};

等待一个条件变量怎么样?这不是你的问题,但你不需要两个信号量。一个用来跟踪性别的变量和一个信号量就足够了。这真是难以置信地不是现实世界的工作方式。男孩+女孩在一个浴室是一个明显的可能性,至少需要10分钟。按照你自己的方式模拟世界。对不起,在调用WaitForSingleObject时出错,需要等待SingleObject异性,无限;