所以我有一个模拟网络摄像头的小程序。所以帧(在我的程序中的数据值)必须保存在2个文件和屏幕上。但是,当我运行我的代码时,我得到了一个分段错误;
#include <iostream>
#include <fstream>
#include <pthread.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
#ifdef WIN32
# include <process.h>
#else
# include <time.h>
#endif
static void Error(const char *str)
{
std::cerr << str << std::endl;
exit(0);
}
class Data
{
public:
Data() : refcount(0), value(0) {}
void ref() { refcount++; }
void unref() { refcount--; }
bool isUnused(){ return ( refcount == 0 ); }
void setValue(int val){ value = val; }
void print(std::ostream &ostr) { ostr << value << std::endl; }
private:
unsigned int refcount;
int value;
};
class Buffer
{
public:
Buffer() : lastProduced(0) {}
public:
Data *getEmptyDataElement()
{
Data *d = 0; /* = empty data element */;
for (int i=0; i<BUFFERSIZE; i++)
{
if (storage[i].isUnused()) {
d = &storage[i];
break;
}
}
return d;
}
Data *getLastProducedData(Data* previous)
{
// check if new element is available
Data *d = lastProduced;
d->ref();
return d;
}
void publish(Data *d) /* update last produced, so getLastProducedData returns the correct element */
{
lastProduced = d;
}
void release(Data *d) /* update handled element, to make it available via getEmptyDataElement */
{
d->unref();
}
private:
static const int BUFFERSIZE = 10;
Data storage[BUFFERSIZE];
Data *lastProduced;
};
static void *start_thread(void *t);
class Thread
{
public:
Thread() : tid(0) {}
void start()
{
if( pthread_create(&tid, 0, start_thread, (void *) this) != 0 )
Error("Error: failed to create thread");
}
void wait()
{
void *status;
pthread_join(tid, &status);
}
static void sleep(unsigned int msecs)
{
#ifdef WIN32
if( SleepEx(msecs, TRUE) != 0 )
Error("Error: SleepEx interrupted");
#else
struct timespec timeout; // timeout value for wait function
// prepare timeout value
timeout.tv_sec = msecs / 1000;
msecs -= timeout.tv_sec * 1000;
timeout.tv_nsec = (1000 * msecs) * 1000;
if( nanosleep(&timeout, 0) != 0 )
Error("Error: nanosleep interrupted or failed");
#endif
}
virtual void run() = 0;
private:
pthread_t tid;
};
static void *start_thread(void *t)
{
reinterpret_cast<Thread *>(t)->run();
return 0;
}
class Producer : public Thread
{
public:
Producer(Buffer &b, long sequenceNumber) : buffer(b), sequenceNumber(sequenceNumber) {}
private:
void run()
{
for(int i = 0; i < 1000; ++i)
{
Data *d = buffer.getEmptyDataElement();
produceData(d);
buffer.publish(d);
}
}
void produceData(Data *d)
{
Thread::sleep((float(rand()) / RAND_MAX) * 1000); // sleep between 0 and 1 sec
d->setValue(sequenceNumber++);
d->print(std::cout);
}
Buffer &buffer;
long sequenceNumber;
};
class Handler : public Thread
{
public:
Handler(Buffer &b, std::ostream &ostr) : buffer(b), ostr(ostr) {}
private:
void run()
{
Data *previous = 0;
while( 1)
{
Data *d = buffer.getLastProducedData(previous);
handleData(d);
buffer.release(d);
previous = d;
}
}
void handleData(Data *d)
{
d->print(ostr);
Thread::sleep((float(rand()) / RAND_MAX) * 1000); // sleep between 0 and 1 sec
}
Buffer &buffer;
std::ostream &ostr;
};
int main()
{
Buffer buff;
std::ofstream file1;
std::ofstream file2;
file1.open ("file1.txt");
file2.open ("file2.txt");
// open the files
Producer p(buff, 0);
Handler h1(buff, std::cout), h2(buff, file1), h3(buff, file2);
p.start();
h1.start();
h2.start();
h3.start();
p.wait();
h1.wait();
h2.wait();
h3.wait();
// wait until producers stopped producing and handlers handled all produced data
return EXIT_SUCCESS;
}
有谁知道我的错在哪里,某处我认为有一个僵局,但我无法弄清楚在哪里。
答案 0 :(得分:0)
我不知道你是否正在寻找它的错误,或者它是否是另一个错误,但......当你用这种方式写Buffer::getEmptyDataElement()
时
Data *getEmptyDataElement()
{
Data *d = 0; /* = empty data element */;
for (int i=0; i<BUFFERSIZE; i++)
{
if (storage[i].isUnused()) {
d = &storage[i];
break;
}
}
return d;
}
你编写的函数可以返回NULL
Data
指针(当使用所有存储时)。
如果您在使用它之前测试返回的指针,但在Producer::run()
void run()
{
for(int i = 0; i < 1000; ++i)
{
Data *d = buffer.getEmptyDataElement();
produceData(d);
buffer.publish(d);
}
}
您将d
指针传递给Producer::produceData()
,而不进行测试和
void produceData(Data *d)
{
Thread::sleep((float(rand()) / RAND_MAX) * 1000); // sleep between 0 and 1 sec
d->setValue(sequenceNumber++); // what if 'd' is NULL?
d->print(std::cout); // what if 'd' is NULL?
}
Producer::produceData()
使用它而不进行测试NULL
。
潜在的崩溃。
与使用Buffer::getLastProducedData()
lastProduced
NULL
的{{1}}相同的潜在问题?publish()
通过Producer::run()
来自Producer::produceData()
的{{1}}收到Data *getLastProducedData(Data* previous)
{
// check if new element is available
Data *d = lastProduced;
d->ref(); // what if 'lastProduced' (and so 'd') is NULL?
return d;
}
测试值?)而不测试它
file1.txt
无论如何:如果您想要我们可以尝试您的计划,您应该给我们file2.txt
和<f:format.date format="d.m.Y - H:i:s">{event.appointment}</f:format.date>
。
P.s:抱歉我的英语不好