迅雷的笔试题

转自:http://blog.csdn.net/baiding1123/article/details/14053957

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

互斥锁和条件变量。

假设有三个线程A, B, C;A线程首先执行,B线程等待A结束后执行,C线程等待B结束后执行,A线程又要等待C线程结束后执行,B再等待A,C再等待B....以此类推,是一个循环等待的过程,每一个线程要做的事情:1.抢到锁,设置标志位为1(告诉上家自己在等待信号);2.收到上家的信号,立即设置标志为为0,并打印出自己的线程号;3.确定下家是否在等待,确定下家在等待后,立即发送信号给下家,再打开锁,usleep(20)(让其他线程抢到锁)。

其中有两个要注意的地方:1.三个线程创建好后,三个线程都在死等待 [A等C,B等A,C等B] 所以首先手动代替C为A发送信号,让程序执行。2.A线程的10次循环结束后,flag标志位是0,而此时C线程还没有执行完毕,C要检查A的标志为是否为1再给A发送信号,所以在A循环结束后把它的flag标志为置为1。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>

#define LP_TIMES    10

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cond_AB = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_BC = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_CA = PTHREAD_COND_INITIALIZER;

//标记
int flag_AB,flag_BC,flag_CA;

//标记检查的线程等待
void th_condflag_wait(int *flag,pthread_cond_t *cond,pthread_mutex_t *mutex)
{
    (*flag) = 1;
    pthread_cond_wait(cond,mutex);
    (*flag) = 0;
}

//标记检查的线程通知
void th_condflag_broadcast(int *flag,pthread_cond_t *cond,pthread_mutex_t *mutex)
{
    while(!(*flag))
    {
        pthread_mutex_unlock(mutex);
        usleep(50);
        pthread_mutex_lock(mutex);
    }
    pthread_cond_broadcast(cond);
}

void *th_fun_A(void *arg)
{
    int i = LP_TIMES;
    while(i--)
    {
        pthread_mutex_lock(&mutex);
        //A wait C
        th_condflag_wait(&flag_CA,&cond_CA,&mutex);

        printf("A%d: %lx\n",10-i,pthread_self());

        //A cond B
        th_condflag_broadcast(&flag_AB,&cond_AB,&mutex);
        pthread_mutex_unlock(&mutex);

        usleep(50);
    }
    //防止C线程最后一次等待A线程时死锁
    flag_CA = 1;
}

void *th_fun_B(void *arg)
{
    int i = LP_TIMES;
    while(i--)
    {
        pthread_mutex_lock(&mutex);
        //B wait A
        th_condflag_wait(&flag_AB,&cond_AB,&mutex);

        printf("B%d: %lx\n",10-i,pthread_self());

        //B cond C
        th_condflag_broadcast(&flag_BC,&cond_BC,&mutex);
        pthread_mutex_unlock(&mutex);

        usleep(50);
    }
}

void *th_fun_C(void *arg)
{
    int i = LP_TIMES;
    while(i--)
    {
        pthread_mutex_lock(&mutex);
        //C wait B
        th_condflag_wait(&flag_BC,&cond_BC,&mutex);

        printf("C%d: %lx\n",10-i,pthread_self());

        //C cond A
        th_condflag_broadcast(&flag_CA,&cond_CA,&mutex);
        pthread_mutex_unlock(&mutex);
        usleep(50);
    }
}

int main(void)
{
    printf("main: %lx\n",pthread_self());

    //保存3个线程的处理函数
    void *(*th_funs[])(void *) =
    {
        th_fun_A,
        th_fun_B,
        th_fun_C
    };

    int th_count = sizeof(th_funs)/sizeof(th_funs[0]);

    pthread_t th[th_count];
    int i;
    for(i = 0;i < th_count;i++)
    {
        //通过线程函数数组记录的函数来创建线程
        if(pthread_create(th+i,NULL,th_funs[i],(void *)i) < 0)
        {
            fprintf(stderr,"th_create: %s\n",
                    strerror(errno));
            exit(1);
        }
        printf("th[%d]: %lx\n",i,th[i]);
    }

    //起始给A线程发出通知,防止A和C死锁
    pthread_mutex_lock(&mutex);
    th_condflag_broadcast(&flag_CA,&cond_CA,&mutex);
    pthread_mutex_unlock(&mutex);

    //回收线程
    for(i = 0;i < th_count;i++)
    {
        pthread_join(th[i],NULL);
        printf("i: %d finished!\n",i);
    }

    return 0;
}

</pthread></errno></string></stdlib></stdio>
时间: 2024-07-29 14:13:07

迅雷的笔试题的相关文章

多线程笔试题(linux)

子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> pthread_attr_t attr; pthread_mutex_t mutex; pthread_cond_t cond; pthread_t pi

Java工程师笔试题整理[校招篇]

隔着两个月即将开始校招了.你是不是也想借着这个机会崭露头角,拿到某些大厂的offer,赢取白富美.走上人生巅峰?当然如果你还没能打下Java基础,一定要先打好Java基础:如何一步一步的学Java - 学习编程 - 知乎专栏.然后再来看一下练习一下各大厂的面试笔试题目. 如果以下内容满足不了你,你还可以去看这篇: 2016校招编程题汇总 - 学习编程 - 知乎专栏 进入主要内容(主要内容整理来自牛客网:牛客网)(以下内容按照各大公司进行划分,对每一公司按照年份进行划分,如果想想下载以下内容,可以

【转】嵌入式软件工程师经典笔试题

嵌入式软件工程师经典笔试题 > 预处理器(Preprocessor) 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情: 1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 2). 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中 有多少秒而不是计算出实际的值,是更清晰而没有代价的. 3).

腾讯web前端开发工程师笔试题及答案

1. 如何实现事件委托? 首先要知道什么是事件委托. 考虑一个列表,在li的数量非常少的时候,为每一个li添加事件侦听当然不会存在太多性能方面的问题,但是当列表非常的长,长到上百上千甚至上万的时候(当然只是一个解释,实际工作中很少遇到这么多li的情况),为每个li添加事件侦听就会对页面性能产生很大的影响. 就像下面这段代码: <!DOCTYPE HTML><html><head><meta charset="utf-8" /><ti

ThoughtWorks笔试题之Merchant&#39;s Guide To The Galaxy解析

一.背景 在某网站上看到ThoughtWorks在武汉招人,待遇在本地还算不错,就投递了简历.第二天HR就打开电话,基本了解了一下情况(工作环境不错,男人妹子比例:1:1,双休,六险一金,满一年年假15天,病假8天,月薪1W--2W).然后立马收到一封:Coding Assignment的笔试题目.网上搜索了一下,发现这个公司还是挺大的,公司面试流程是出了名的繁杂和苛刻.据说有8轮:电话面试=>笔试=>Homework=>结对编程(中午管饭)=>技术面试=>PM面试=>

java各公司笔试题集1

IBM笔试题 注:IBM笔试题一小时之内完成,题目全部用英文描述,这里用中文表述 一.名词解释 1.Eclipse 2.J2EE 3.EJB 4.Ajax 5.Web service 二.找出以下代码问题 public class test{ public void print(String str){ char[] s=str: } } public class a{ public static void main(String [] args){ puts() } } 三.写出以下输出 pu

腾讯笔试题:满二叉排序树,任给3个子节点,找他们最大的公共父节点

腾讯笔试题出现了和这个类似的题目,没做出来,现在来好好解决这个问题吧,先从基本的开始. 先吐槽一下:感觉算法设计什么的,真的超级难,也许是我头脑太笨,转不过弯来吧,呵呵. 题目是这样的:一棵满二叉排序树,有K层,节点的值依次为 1~2k-1.现在告诉你树的高度是4层,给定你3个节点,比如9,11, 13,那么最大的公共父节点是12. 现在想起来这题我已经想出来一半了呀,但是大概人在紧张的时候大脑会思维短路,跳不出原有的思维陷阱.想法是这样的: 1. 首先是从根节点开始,如果给的三个叶节点的值其中

2017CVTE笔试题

下面是凭记忆整理的2017CVTE校招笔试题,基本上全都是我不会或很模糊的题,为了更好突出重点我以问答题的形式来描述题目. 1. 中序遍历是属于层次遍历.广度优先遍历.深度优先遍历中的哪一种? 答:层次遍历是指一层一层的遍历树中的节点,广度优先遍历是指遍历完它所有的兄弟节点后再开始遍历其孩子节点,因此层次遍历也属于广度优先遍历.深度优先遍历就是顺着节点的孩子节点一直往下搜索,直到没有孩子节点时才开始搜索叶子节点,常见的前序遍历.中序遍历.后序遍历就是属于深度优先遍历. 2. 产生死锁的4个条件,

c++笔试题贪吃蛇问题

贪吃蛇 现在有一个N*M(N,M=100)的方形矩形,在这个矩形的每一个方格上都放有一个随机值,一条可爱的小蛇从矩形的 左上角开始出发,每次移动都只能移动一格,向右或向下,而每到达一格贪吃的小蛇都会吧该位置上的值吃个一干二净,直到到达右下角时停止.而贪吃的小蛇不怕撑死,它只想吃到最多,并输出路径. #include <iostream> #include<string> #include <cstring> #include<vector> #include