免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: baohuaihuai
打印 上一主题 下一主题

新鲜出炉Google面试题一道(多线程) [复制链接]

论坛徽章:
0
61 [报告]
发表于 2007-10-28 21:38 |只看该作者
线程数组,每个线程启动的时候传入一个参数作为输出内容,输出以后把文件压入队列中后一个线程的缓冲区内,队列末尾的线程将文件压入队首的线程缓冲区内。

线程队列初始化完成后,初始化输出文件,将相应的文件直接压入对应的线程缓冲区内。

论坛徽章:
0
62 [报告]
发表于 2007-10-30 09:17 |只看该作者
要是题目变变,说每个文件的输入都是不同的什么东西,或许是个结构,或许是个字符串,或许是个整数,只是在输入的时候需要准守一定的次序规则,那又该如何呢?所以我还是赞同,这个题目考得是对多线程的调度,大家还是不要在那些字母上玩弄小聪明了!

论坛徽章:
0
63 [报告]
发表于 2007-10-30 09:42 |只看该作者
mark

论坛徽章:
0
64 [报告]
发表于 2007-10-30 10:10 |只看该作者
mmap后直接操作内存??

论坛徽章:
0
65 [报告]
发表于 2007-10-30 10:38 |只看该作者
原帖由 DaYuTou 于 2007-10-26 20:46 发表
线程1函数的代码大致如下
{
open(a);//打开a文件
open(b);//打开b文件
lseek(b,3,SEEK_SET);//b从位置3开始写
open(c);//打开c文件
lseek(c,2,SEEK_SET);//c从位置2开始写
open(d);//打开d文件
lseek(d ...


思路很巧妙,但是不严谨。

如果程序启动之后马上SIGINT,查看文件内容,不能保证正确。

论坛徽章:
0
66 [报告]
发表于 2007-10-30 10:39 |只看该作者
这道题其实就是考“锁链”。

是道好题! 我拿去虐待学生

论坛徽章:
0
67 [报告]
发表于 2007-10-30 10:52 |只看该作者

回复 #5 wuxiangzhi 的帖子

真的很不错, 看懂了, last_num 用的很好!!!

论坛徽章:
0
68 [报告]
发表于 2007-10-30 11:10 |只看该作者
嗬嗬,简单的问题想复杂了

论坛徽章:
0
69 [报告]
发表于 2007-10-30 11:17 |只看该作者
原帖由 g_hk 于 2007-10-30 10:52 发表
真的很不错, 看懂了, last_num 用的很好!!!


5楼的答案大概看了看,我相信没答到点子上。

根据我多年的教学经验,我揣测出题者的意图是考验学生是否会灵活利用mutex或信号量构造锁链。


用锁链实现,代码要短一半以上,而且不需要出现“第一次写”这种......丑陋的结构(请原谅我的直率,找不到更好的形容词)。

论坛徽章:
0
70 [报告]
发表于 2007-10-30 12:00 |只看该作者

贴一个可运行的版本

参考了五楼的代码, 用下面的命令编译。
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();

}


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP