这是我的代码,它可以工作,但经过几次迭代后,它会停止而没有任何错误,可能是因为某些种族或死锁。
代码的目标是为编码应用程序建模:在创建一些伪随机帧之后,我的管道的各个阶段首先给出帧的类型,然后用一些随机操作对其进行编码。
为了做到这一点,我使用了两个不同的线程向量(每个阶段一个)与一些共享队列同时使用,一旦一个线程推送了一个帧,它被另一个向量中的另一个弹出,并被“编码” #include <iostream>
#include <vector>
#include <algorithm>
#include "SafeQueue.h"
using namespace std;
const int DATA_MAG = 256;
struct Frame
{
int num;
char type;
bool encoded;
vector<vector<int>> grid;
};
void do_join(thread& t)
{
t.join();
}
void join_all(vector<thread>& v)
{
for_each(v.begin(),v.end(),do_join);
}
void create_input (Queue<Frame>& stream, int num_frames, int height, int width)
{
for (int i = 0; i < num_frames; i++)
{
vector<vector<int>>tmp_grid(height, vector<int>(width, 0));
Frame frame;
for (int j = 0; j < height; j++)
{
for (int k = 0; k < width; k++)
{
tmp_grid[j][k] = rand()%DATA_MAG;
}
}
frame.grid = tmp_grid;
frame.num = i;
stream.push(frame);
}
}
void decide_type(int preset, Queue<Frame>& stream, Queue<Frame>& typed, vector<char>& param, int num_frames)
{
cout<<"hello from decide"<<" "<<endl;
for(int i = 0; i < num_frames; i++)
{
Frame tmp = stream.pop();
int j = rand() % 10;
if(j < preset)
{
tmp.type = 'I';
}
else
{
tmp.type = 'B';
}
param[tmp.num] = tmp.type;
typed.push(tmp);
}
}
void decode_flow(int preset, Queue<Frame>& typed, vector<Frame>& encoded,
vector<char>& parameters, int num_frames, int height, int width)
{
cout<<"hello from decode"<<" "<<endl;
for(int i = 0; i < num_frames; i++)
{
Frame f = typed.pop();
if (f.type == 'I')
{
cout<<"hi from I"<<" "<<endl;
for (int j = 0; j < height; j++)
{
for (int k = 0; k < width; k++)
{
f.grid[j][k] = f.grid[j][k] * 2;
}
}
}
else cout<<"hi from B"<<" "<<endl;
encoded.push_back(f);
}
}
int main()
{
srand(time(NULL));
int num_threadsXstage = 2;
int width = 500;
int height = 500;
int num_frames = 100;
int frames_thread = num_frames/num_threadsXstage;
int preset = 3;
vector<Frame> final;
//Vectors of threads
vector<thread> typer;
vector<thread> encoder;
//Vector of parameters
vector<char> parameters(num_frames);
//Working queues
Queue<Frame> created;
Queue<Frame> typed;
//Final vector
vector<Frame> encoded(num_frames);
//Movie creation
create_input(created, num_frames, height, width);
for (int i = 0; i < num_threadsXstage; i++)
{
//stage 1
typer.push_back(thread(bind(&decide_type, preset, ref(created),
ref(typed), ref(parameters), frames_thread)));
//stage 2
encoder.push_back(thread(bind(&decode_flow, preset, ref(typed), ref(encoded),
ref(parameters), frames_thread, height, width)));
}
// JOIN
join_all(typer);
join_all(encoder);
for (int i = 0; i < num_frames; i++)
{
Frame k = typed.pop();
cout<<k.type<<" ";
}
cout<<endl<<endl;
for (int i = 0; i < num_frames; i++)
{
cout<<parameters[i]<<" ";
}
}
这是我的线程安全队列的代码,或者至少应该是。
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
using namespace std;
template <typename T>
class Queue
{
private:
queue<T> queue_;
mutex mutex_;
condition_variable cond_;
public:
T pop()
{
unique_lock<std::mutex> mlock(mutex_);
while (queue_.empty())
{
cond_.wait(mlock);
}
auto val = queue_.front();
queue_.pop();
return val;
}
void pop(T& item)
{
unique_lock<std::mutex> mlock(mutex_);
while (queue_.empty())
{
cond_.wait(mlock);
}
item = queue_.front();
queue_.pop();
}
void push(const T& item)
{
unique_lock<std::mutex> mlock(mutex_);
queue_.push(item);
mlock.unlock();
cond_.notify_one();
}
Queue()=default;
Queue(const Queue&) = delete; // disable copying
Queue& operator=(const Queue&) = delete; // disable assignment
};
答案 0 :(得分:2)
在所有线程完成后,您从typed
队列中提取所有排队的帧 - 但这是处理阶段之间的中间队列,现在是空的。对typed.pop()
的调用将永久阻止。
您应该从输出队列encoded
中提取帧。