Producer-Consumer用c ++中的clone2和semaphores实现

时间:2014-10-11 22:32:51

标签: c++ multithreading clone mutex producer-consumer

我使用clone2()和信号量实现了一个使用c ++的生产者使用者,但它有一个意想不到的行为。

以下是代码:

#include <iostream>
#include <semaphore.h>
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <errno.h>
#include <mutex>
#include <sys/wait.h>

using namespace std;

sem_t empty, full;
mutex mutexSem;

int var = 1;
int items[10];
int in = 0;
int out = 0;

static int produce(void * arg) {

  while (true) {
      sem_wait(&empty);
      mutexSem.lock();
      cout << "produce position: " << in << endl;
      items[in] = var++;
      in = (in+1) % 10;
      mutexSem.unlock();
      sem_post(&full);
    }

  }

  static int consume(void *arg) {

    while (true) {
      sem_wait(&full);
      mutexSem.lock();
      cout << "consume position: " << out << endl;
      items[out] = 0;
      out = (out + 1 ) % 10;
      mutexSem.unlock();
      sem_post(&empty);
    }

  }

int
main(int argc, char *argv[]) {

  int emptyResponse = sem_init(&empty, 0, 10);
  int fullResponse = sem_init(&full, 0, 0);
  void ** child_stack;

  child_stack = (void **) malloc(16384) + 16384 / sizeof(*child_stack);

  if (errno != 0 || emptyResponse != 0
     || fullResponse != 0) {
    cout << "errNo->" << errno << endl;
  }

  clone(produce, child_stack, CLONE_VM | CLONE_FILES , NULL);
  sleep(4);
  clone(consume, child_stack, CLONE_VM | CLONE_FILES, NULL);

  return 0;

}

我编译代码

  

g ++ -std = c ++ 11 clone2.cpp -o clone2 -lpthread

每次运行代码时都会产生不同的结果。我想生产一个无限的生产者/消费者,每次生产一个项目,然后我将被消费。我不知道为什么在生产10件物品后,它会消耗10件物品并且工艺完成。我不知道为什么我必须在两个线程之间使用sleep(anyNumber),即使它不会做任何事情。 有人可以告诉我,如果我设置的FLAGS没问题,以及这个克隆是如何工作的。

这是输出的示例:

  

产生:0

     

产生:1

     

产生:2

     

产生:3

     

产生:4

     

产生:5

     

产生:6

     

产生:7

     

产生:8

     

产生:9

     消耗:0

     消耗:1

     消耗:2

     消耗:3

     消耗:1515067019

     消耗:5

     消耗:6

     消费:7

     消耗:8

     消耗:9

有时是喜欢它,有时它有分段错误,有时它只是不打印任何数字所以它会显示为

  消费:

     消耗:5

等等......

注意:使用clone2()是强制性的,我使用的是ubuntu 14.04 LTS,Intel core i7 64位

谢谢!

1 个答案:

答案 0 :(得分:0)

当你创建新的&#34;线程&#34;你告诉他们与父进程共享内存。然而,有两个大问题:

  1. 您为孩子们创建的堆栈也是共享的,因此两个&#34;线程&#34;将有相同的堆栈。
  2. 父进程退出,我不确定分配的共享内存会发生什么,但可能会被释放。
  3. 这两件事都会导致undefined behavior

    第一个问题可以通过两个堆栈来解决,每个堆栈一个。第二个问题可以通过父进程waiting解决,让孩子退出。