码迷,mamicode.com
首页 > 编程语言 > 详细

c++多线程编程:常见面试题

时间:2016-10-11 20:53:40      阅读:303      评论:0      收藏:0      [点我收藏+]

标签:

题目:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码

子线程与主线程必有一个满足条件(flag == num),不满足条件的那个线程不可能获取unique_lock(会在wait中释放),只有满足条件的线程才能获取锁,执行程序

mutex m;//保护条件的互斥访问
condition_variable cond;//条件变量
int flag = 10;//条件
void fun(int num) {
    for (int i = 0; i<50; i++) {
        unique_lock<mutex> lk(m);//A unique lock is an object that manages a mutex object with unique ownership in both states: locked and unlocked.  
        while (flag != num)
            cond.wait(lk);//在调用wait时会执行lk.unlock()  
        for (int j = 0; j<num; j++)
            cout << j << " ";
        cout << endl;
        flag = (num == 10) ? 100 : 10;
        cond.notify_one();//被阻塞的线程唤醒后lk.lock()恢复在调用wait前的状态  
    }
}
int main() {
    thread child(fun, 10);
    fun(100);
    child.join();
    
    system("pause");
    return 0;
}

题目:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

mutex m;
condition_variable cond;
int loop = 10;
int flag = 0;

void func(int id)
{
    for (int i = 0; i < loop; ++i)
    {
        unique_lock<mutex> lk(m);
        while (flag != id)
            cond.wait(lk);
        cout << static_cast<char>(A + id) << " ";
        flag = (flag + 1) % 3;
        cond.notify_all();
    }
}

void main()
{
    thread A(func, 0);
    thread B(func, 1);
    func(2);
    cout << endl;

    A.join();
    B.join();

    system("pause");
}

题目(google笔试题):有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:
A:1 2 3 4 1 2....
B:2 3 4 1 2 3....
C:3 4 1 2 3 4....

D:4 1 2 3 4 1....

mutex m;
condition_variable cond;
int loop = 10;
int flag;

void func(int num)
{
    for (int i = 0; i < loop; ++i)
    {
        unique_lock<mutex> lk(m);
        while (num != flag)
            cond.wait(lk);
        cout << num + 1 << " ";
        flag = (flag + 1) % 4;
        cond.notify_all();
    }
}

void main(int argc,char *argv[])
{
    flag = atoi(argv[1]);
    thread one(func, 1);
    thread two(func, 2);
    thread three(func, 3);
    func(0);
    one.join();
    two.join();
    three.join();
    cout << endl;

    system("pause");
}

读者写者问题

这也是一个非常经典的多线程题目,题目大意如下:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写。

这里采用copy on write(写时拷贝)实现,主要要理解智能指针std::shared_ptr的用法,用访问vector替代题目中的文件,代码如下:

http://c.biancheng.net/cpp/html/2601.html

int readerNum = 0;
mutex m;
mutex rw;

void writer()
{
    rw.lock();
    cout << "i am writing" << endl;
    rw.unlock();
}

void reader()
{
    m.lock();
    if (readerNum == 0)
        rw.lock();
    readerNum++;
    m.unlock();
    cout << "i am reading" << endl;
    m.lock();
    readerNum--;
    if (readerNum == 0)
        rw.unlock();
    m.unlock();
}

void main() 
{
    thread wr1(writer);
    thread rd1(reader);

    wr1.join();
    rd1.join();

    system("pause");
}

线程安全的queue

STL中的queue是非线程安全的,一个组合操作:front(); pop()先读取队首元素然后删除队首元素,若是有多个线程执行这个组合操作的话,可能会发生执行序列交替执行,导致一些意想不到的行为。因此需要重新设计线程安全的queue的接口。

template<typename T>
class threadsafe_queue
{
private:
    mutable std::mutex mut;
    std::queue<T> data_queue;
    std::condition_variable data_cond;
public:
    threadsafe_queue() {}
    threadsafe_queue(threadsafe_queue const& other)
    {
        std::lock_guard<std::mutex> lk(other.mut);
        data_queue = other.data_queue;
    }
    void push(T new_value)//入队操作  
    {
        std::lock_guard<std::mutex> lk(mut);
        data_queue.push(new_value);
        data_cond.notify_one();
    }
    void wait_and_pop(T& value)//直到有元素可以删除为止  
    {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this] {return !data_queue.empty(); });
        value = data_queue.front();
        data_queue.pop();
    }
    std::shared_ptr<T> wait_and_pop()
    {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this] {return !data_queue.empty(); });
        std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
        data_queue.pop();
        return res;
    }
    bool try_pop(T& value)//不管有没有队首元素直接返回  
    {
        std::lock_guard<std::mutex> lk(mut);
        if (data_queue.empty())
            return false;
        value = data_queue.front();
        data_queue.pop();
        return true;
    }
    std::shared_ptr<T> try_pop()
    {
        std::lock_guard<std::mutex> lk(mut);
        if (data_queue.empty())
            return std::shared_ptr<T>();
        std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
        data_queue.pop();
        return res;
    }
    bool empty() const
    {
        std::lock_guard<std::mutex> lk(mut);
        return data_queue.empty();
    }
};

 

c++多线程编程:常见面试题

标签:

原文地址:http://www.cnblogs.com/ljygoodgoodstudydaydayup/p/5950400.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!