【发布时间】:2014-10-11 22:32:50
【问题描述】:
我正在使用 c++ 使用 clone2() 和信号量来实现一个生产者消费者,但它有一个意外的行为。
代码如下:
#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 bits
谢谢!
【问题讨论】:
-
一个不相关的提示:不要检查
errno,除非之前的函数确实失败了,除非确实发生了错误,errno的状态是未定义的。另外,如果发生错误,需要立即检查errno,调用其他函数可能会改变值。
标签: c++ multithreading clone mutex producer-consumer