- 论坛徽章:
- 0
|
贴一个可运行的版本
参考了五楼的代码, 用下面的命令编译。
g++ -lpthread google_pthread.cpp
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;
#define ID_WORKER_1 1
#define ID_WORKER_2 2
#define ID_WORKER_3 3
#define ID_WORKER_4 4
#define MAX_ID 4
class OutStream;
class Worker
{
private:
char buffer[4];
int m_id;
public:
Worker(int id, char* str) : m_id(id) {
memcpy(buffer, str, 4);
}
void doWork(OutStream* out_stream);
int getID() { return m_id; }
};
class OutStream
{
private:
int m_fd;
int m_worker;
string m_filename;
pthread_mutex_t m_lock;
public:
OutStream(string filename, int id_worker) : m_filename(filename) {
m_worker = id_worker;
pthread_mutex_init(&m_lock, NULL);
m_fd = open((char*)m_filename.c_str(), O_CREAT | O_WRONLY , S_IRUSR|S_IWUSR);
if (m_fd < 0) {
printf("create file %s failed , exit !\n", m_filename.c_str());
exit(1);
}
}
~OutStream() {
close(m_fd);
pthread_mutex_unlock(&m_lock);
}
int getFD() { return m_fd; }
string getFileName() { return m_filename; }
bool captureToken( Worker* p_worker) {
if (p_worker->getID() != m_worker) {
return false;
}
if ( pthread_mutex_trylock(&m_lock) ) {
return false;
}
// pthread_mutex_lock(&m_lock);
return true;
}
void releaseToken() {
// let next worker to write
m_worker++;
if (m_worker > ID_WORKER_4 ) {
m_worker = ID_WORKER_1;
}
pthread_mutex_unlock(&m_lock);
}
};
void Worker::doWork(OutStream* out_stream)
{
write(out_stream->getFD(), (void*)buffer, strlen(buffer));
cout << "Worker " << m_id << " write output to file " << out_stream->getFileName() << endl;
}
// declare workers
Worker worker_1(ID_WORKER_1, "1 ");
Worker worker_2(ID_WORKER_2, "2 ");
Worker worker_3(ID_WORKER_3, "3 ");
Worker worker_4(ID_WORKER_4, "4 ");
// declare out streams
OutStream streamA("./fileA", ID_WORKER_1);
OutStream streamB("./fileB", ID_WORKER_2);
OutStream streamC("./fileC", ID_WORKER_3);
OutStream streamD("./fileD", ID_WORKER_4);
void *work_thread(void *arg)
{
pthread_t pid;
Worker *p_worker;
p_worker = (Worker* )arg;
pid = pthread_self();
pthread_detach(pid);
while(1) {
if ( streamA.captureToken(p_worker) ) {
p_worker->doWork(&streamA);
streamA.releaseToken();
}
if ( streamB.captureToken(p_worker) ) {
p_worker->doWork(&streamB);
streamB.releaseToken();
}
if ( streamC.captureToken(p_worker) ) {
p_worker->doWork(&streamC);
streamC.releaseToken();
}
if ( streamD.captureToken(p_worker) ) {
p_worker->doWork(&streamD);
streamD.releaseToken();
}
}
}
int main()
{
pthread_t ntid;
pthread_create(&ntid, NULL, work_thread, &worker_1);
pthread_create(&ntid, NULL, work_thread, &worker_2);
pthread_create(&ntid, NULL, work_thread, &worker_3);
pthread_create(&ntid, NULL, work_thread, &worker_4);
pause();
}
|
|
|