精华内容
下载资源
问答
  • 多线程练习
    2020-12-11 09:09:33

    python多线程练习题

    多线程练习题目,涉及知识点较多,属于很好的练习题。

    题目要求

    通过多线程实现类似linux中的>>功能,也就是将日志记录到指定的文件中。

    题目分析

    基本为main.py写主要处理逻辑,utils.py构造工具类及对应的方法。

    main.py

    定义Server()类,类中定义方法输出内容。

    实例化工具类,启动线程,设置标准输出和错误输出至日志文件。

    实例化Server()类并调用方法进行内容的持续输出。

    utils.py

    定义工具类,工具类需要传入参数:日志名称。

    首先判断日志是否存在,若不存在则创建,然后写入日志;存在则追加写入日志。

    实现

    main.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    import sys

    from queue1.log_out.utils import TraceLog

    class Server(object):

    def log(self):

    print("start server")

    for i in range(100):

    print(i)

    print("end server") #print的实现是调用sys.stdout.write()方法

    if __name__ == "__main__":

    traceLog = TraceLog("main.log")

    traceLog.start()

    sys.stdout = traceLog

    sys.stderr = traceLog

    server = Server()

    server.log() #print将会调用traceLog.write()方法

    utils.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    import codecs

    from threading import Thread, Lock

    import os

    class TraceLog(Thread):

    def __init__(self, logName):

    super(TraceLog, self).__init__() #调用父类的初始化方法

    self.logName = logName

    self.lock = Lock()

    self.contexts = []

    self.isFile()

    def isFile(self):

    if not os.path.exists(self.logName):

    with codecs.open(self.logName, 'w') as f:

    f.write("this log name is :{0}\n".format(self.logName))

    f.write("start log\n")

    def write(self, context):

    self.contexts.append(context) #将需要输出的内容追加至列表中

    def run(self):

    while 1:

    self.lock.acquire()

    if len(self.contexts) != 0:

    with codecs.open(self.logName, 'a') as f: #追加方式写入文件

    for context in self.contexts:

    f.write(context)

    del self.contexts[:] #每次写入完成后清空列表

    self.lock.release()

    输出结果

    当前目录下会生成main.log文件,文件内容如下

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    this log name is :main.log

    start log

    start server

    0

    1

    2

    .

    .

    98

    99

    end server

    涉及文件读写、锁、多线程、sys模块、os模块等内容。

    更多相关内容
  • 手写多线程demo,模拟数据库练习。感谢技术分享感谢技术分享感谢技术分享..感谢技术分享感谢技术分享感谢技术分享..
  • 多线程练习程序 之 模拟火车票售票系统01版-附件资源
  • 运用多线程技术,练习Thread类得run方法和start方法。运用进度条显式表示下载进度。java多线程之赛马程序
  • Java多线程练习

    2021-04-26 14:16:59
    Java多线程练习 在main方法中使用三个线程,向一个List集合中按顺序添加1到10共十个数字,添加完成后在控制台打印这个List的值(应该是[1,2,3,4,5,6,7,8,9,10]),然后结束程序执行。 import java.util.ArrayList; ...

    Java多线程练习

    在main方法中使用三个线程,向一个List集合中按顺序添加1到10共十个数字,添加完成后在控制台打印这个List的值(应该是[1,2,3,4,5,6,7,8,9,10]),然后结束程序执行。

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ThreadTest {
        private int flag = 1;
        private int count = 1;
    
        private final Lock lock = new ReentrantLock();
        private final Condition conditionA = lock.newCondition();
        private final Condition conditionB = lock.newCondition();
        private final Condition conditionC = lock.newCondition();
        volatile List<Integer> list = new ArrayList<>();
    
        public void addA() {
            if (count >= 9) return;
            lock.lock();
            try {
                if (flag != 1) {
                    conditionA.await();
                }
                list.add(count);
                count++;
                flag = 2;
                // 唤醒B
                conditionB.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void addB() {
            if (count >= 9) return;
            lock.lock();
            try {
                if (flag != 2) {
                    conditionB.await();
                }
                list.add(count);
                count++;
                flag = 3;
                // 唤醒C
                conditionC.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
    
        public void addC() {
            if (count >= 9) return;
            lock.lock();
            try {
                if (flag != 3) {
                    conditionC.await();
                }
                list.add(count);
                count++;
                flag = 1;
                // 唤醒A
                conditionA.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public List<Integer> getList() {
            return list;
        }
    }
    
    public class Test3 {
    
        static Thread t1 ,t2,t3;
    
        public static void main(String[] args) {
            List<Thread> threadList = new ArrayList<>();
            ThreadTest threadTest = new ThreadTest();
            t1 = new Thread(() -> {
                for (int i = 1; i <= 4; i++) {
                    threadTest.addA();
                }
            });
    
            t2 = new Thread(() -> {
                for (int i = 1; i <= 4; i++) {
                    threadTest.addB();
                }
            });
    
            t3 = new Thread(() -> {
                for (int i = 1; i <= 4; i++) {
                    threadTest.addC();
                }
            });
            //把Thread添加到集合
            threadList.add(t1);
            threadList.add(t2);
            threadList.add(t3);
            //启动线程
            t1.start();
            t2.start();
            t3.start();
    
            for(Thread item : threadList){
                try {
                    //等待子线程执行后才执行主线程
                    item.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            List<Integer> integers = threadTest.getList();
            Object[] array = integers.toArray();
            System.out.println(Arrays.toString(array));
        }
    }
    
    展开全文
  • JAVA多线程练习题的答案。都是一些基本的练习题。对初学者有帮助
  • java基础之多线程练习题,博客访问地址: http://blog.csdn.net/u014028392/article/details/76906801
  • 多线程练习题java

    2015-11-09 22:08:03
    java多线程初学者练习题目,供初学者练习使用
  • 鱼刺多线程练习源码。源码调用了鱼刺类_多线程应用.ec。
  • 多线程练习本期可能有点偏离但将的多线程是很有实质性的。 线程_启动 () 线程_挂起 () 线程_恢复 () 线程_销毁 ()
  • 鱼刺多线程练习demo
  • 多线程练习

    千次阅读 2019-02-16 22:47:34
    写两个线程,一个线程打印1-52,另一个线程打印A-Z,打印顺序为12A34B…5152Z //写两个线程,一个线程打印1-52,另一个线程打印A-Z,打印顺序为12A34B...5152Z class Print { private Integer num=1; private Integer...

    写两个线程,一个线程打印1-52,另一个线程打印A-Z,打印顺序为12A34B…5152Z

    //写两个线程,一个线程打印1-52,另一个线程打印A-Z,打印顺序为12A34B...5152Z
    
    class Print
    {
        private Integer num=1;
        private Integer flag=1;
        synchronized public void printNum()
        {
            while(num<27)
            {
                if(flag!=1)
                {
                    try {
                        wait();  //等待打印字母
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //打印数字
                if(num<27) //加判断是因为最后一次num=26,数字线程等待字母线程,当字母打印结束,
                    // num=27,会唤醒数字线程,那么数字线程将会以num=27继续执行
                {
                    System.out.print(num*2-1);
                    System.out.print(num*2);
                    flag=2;
                    notify();//唤醒打印字母的线程
                }
            }
        }
        synchronized  public void printLetter()
        {
            while(num<27)
            {
                if(flag!=2)
                {
                    try {
                        wait(); //此时应该打印数字。等待
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //打印字母
                System.out.print((char)(num-1+'A'));
                num++;
                flag=1;
                notify();  //唤醒打印字母的线程
            }
    
        }
    }
    
    public class Print1A {
        public static void main(String[] args)
        {
            Print print=new Print();
            Thread numThread=new Thread(new Runnable() {
                @Override
                public void run() {
                    print.printNum();
                }
            });
            Thread letterThread=new Thread(new Runnable() {
                @Override
                public void run() {
                    print.printLetter();
                }
            });
            numThread.start();
            letterThread.start();
        }
    }
    

    12A34B56C78D910E1112F1314G1516H1718I1920J2122K2324L2526M2728N2930O3132P3334Q3536R3738S3940T4142U4344V4546W4748X4950Y5152Z

    编写一个程序,启动三个线程,三个线程的名称分别是A,B,C;
    // 每个线程将自己的名字在屏幕上打印5遍,打印顺序是
    //ABCABCABCABCABC

    //编写一个程序,启动三个线程,三个线程的名称分别是A,B,C;
    // 每个线程将自己的名字在屏幕上打印5遍,打印顺序是
    //ABCABCABCABCABC
    
    class PrintABCI
    {
        private Integer flag=1;
        private Integer count=1;  //打印次数
    
        public synchronized void printA()
        {
            while(flag!=1 )
            {
                try {
                    wait();  //等待打印B或C
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.print('A');
            flag=2;
            notifyAll();
        }
        public synchronized void printB()
        {
            while(flag!=2 )
            {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.print('B');
            flag=3;
            notifyAll();
        }
    
        public synchronized void printC()
        {
            while(flag!=3)
            {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.print('C');
            count++;
            flag=1;
            notifyAll();
        }
    }
    public class PrintABC {
        public static void main(String[] args) {
            PrintABCI print=new PrintABCI();
            new Thread(new Runnable()
            {
                @Override
                public void run() {
                    for(int i=0;i<5;i++)
                    print.printA();
                }
            }).start();
    
            new Thread((new Runnable() {
                @Override
                public void run() {
                    for(int i=0;i<5;i++)
                    print.printB();
                }
            })).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int i=0;i<5;i++)
                    print.printC();
                }
            }).start();
        }
    
    }
    

    在这里插入图片描述

    展开全文
  • 多线程练习-易语言

    2021-06-12 16:11:53
    多线程练习
  • 转载:一些c++多线程习题 - geloutingyu - 博客园 (cnblogs.com) 知识点: this_thread::yield(); //当前线程放弃执行,操作系统调度另一线程继续执行 自己手写练习才有感觉: 第一题:子线程循环10次,接着主线...

    转载:一些c++多线程习题 - geloutingyu - 博客园 (cnblogs.com)

    知识点:

    this_thread::yield(); //当前线程放弃执行,操作系统调度另一线程继续执行

    ifstream in(fileName);            //ifstream 是针对文件读取的流
    ofstream out(fileName, ios::app); //ofstream 是针对文件写入的流

    文件流对象有两个可用于随机文件访问的成员函数:tellp 和 tellg
    tellp 用于返回写入位置,tellg 则用于返回读取位置

    自己手写练习才有感觉:

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

    方法一:采用this_thread::yield();

    #include <thread>
    #include <mutex>
    using namespace std;
    
    const int countNum = 50;
    int flag = 100;
    mutex mu;
    
    void fun(int num,string_view str)
    {
        for (int i=0;i< countNum;++i)
        {
            while (num != flag)
            {
                this_thread::yield(); //当前线程放弃执行,操作系统调度另一线程继续执行
            }
            lock_guard<mutex> lock(mu);
            for (int j=0;j<flag;++j)
            {
                cout << str << ":" << j << endl;
            }
            flag = (flag == 10 ? 100 : 10);     
        }
    }
    
    int main()
    {
        thread A(fun, 10, "child");
        fun(100, "father");
        A.join(); 
        return 0;
    }

    总结:fun(100, "father");要放在join之间,子线程A先于函数执行前创建了,主要是要让主线程先跑起来,this_thread::yield();使当前线程停止,让另外线程启动。

    方法二:采用条件变量condition_variable

    #include <mutex>
    #include <condition_variable>
    using namespace std;
    
    const int countNum = 50;
    int flag = 10;
    condition_variable cv;
    mutex mu;
    
    void fun(int num,string_view str)
    {
        for (int i=0;i< countNum;++i)
        {     
            unique_lock<mutex> lock(mu);  
            cv.wait(lock, [&]{return num == flag; });
            for (int j=0;j<flag;++j)
            {
                cout << str << ":" << j << endl;
            }
            flag = (flag == 10 ? 100 : 10);    
            cv.notify_one();//唤醒被锁住的线程
        }
    }
    
    int main()
    {
        thread A(fun, 10, "child");
        fun(100, "father");
        A.join(); 
        return 0;
    }

    总结:condition_variable 只能和unique_lock搭配使用,原因可以看C++11:为什么 std::condition_variable 使用 std::unique_lock? - IT工具网 (coder.work)

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

    方法一:采用this_thread::yield();

     方法二:采用条件变量condition_variable

     总结:注意cv.wait 中填写的条件是 如果为真则执行接下来的代码。

    第三题:(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....

    #include <thread>
    #include <mutex>
    #include <condition_variable>
    #include <fstream>
    using namespace std;
    mutex mu;
    condition_variable cv;
    const string fileName = "D://vsTest//BeStrong//txt//strong_";
    
    ofstream f0(fileName+"A.txt");
    ofstream f1(fileName + "B.txt");
    ofstream f2(fileName + "C.txt");
    ofstream f3(fileName + "D.txt");
    
    ofstream* file[4];
    int v[] = {4,1,2,3};
    int a =0, b = 0, c = 0, d = 0;
    void fun(int x,int num)
    {
       while (num--)
       {
           for (int i=0;i<4;i++)
           {
               unique_lock<mutex> lock(mu);
               if (x==1)
               {
                   cv.wait(lock, [&] { return v[i] == 4; });
                   (*file[i]) << 1;
                   v[i] = 1;
                   a++;
                   lock.unlock();
                   cv.notify_all();
                  
               }
               else if (x == 2)
               {
                   cv.wait(lock, [&] { return v[i] == 1; });
                   (*file[i]) << 2;
                   v[i] = 2;
                   b++;
                   lock.unlock();
                   cv.notify_all();
               }
               else if (x == 3)
               {
                   cv.wait(lock, [&] { return v[i] == 2; });
                   (*file[i]) << 3;
                   v[i] = 3;
                   c++;
                   lock.unlock();
                  
                   cv.notify_all();
               }
               else
               {
                   cv.wait(lock, [&] { return v[i] == 3; });
                   (*file[i]) << 4;             
                   v[i] = 4;
                   d++;
                   lock.unlock();
                   cv.notify_all();
               }
           }
       }
    }
    
    int main()
    {
        file[0] = &f0;
        file[1] = &f1;
        file[2] = &f2;
        file[3] = &f3;
        thread t0(fun,1,10);
        thread t1(fun, 2, 10);
        thread t2(fun, 3, 10);
        fun(4,10);
        t0.join();
        t1.join();
        t2.join();
    
        for (size_t i = 0; i < 4; i++)
        {
            file[i]->close();
        }
        return 0;
    }

     总结:我在每个线程中放了一个变量,原本以为每个变量应该是只差1,查看结果如图,说明线程并不是顺序执行的,即使用条件变量,这本来就是线程的特点,随机性。但结果是顺序。这就是多线程并发的优势。

    第四题:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写

    #include <thread>
    #include <mutex>
    #include <condition_variable>
    #include <fstream>
    using namespace std;
    mutex mu;
    condition_variable cv;
    const string fileName = "D://vsTest//BeStrong//txt//strong_A.txt";
    
    ifstream in(fileName);            //ifstream 是针对文件读取的流
    ofstream out(fileName, ios::app); //ofstream 是针对文件写入的流
    
    int cnt = 0;
    void write()
    {
        char ch;
        while (true)
        {
            unique_lock<mutex> lock(mu);
            ch = getchar();
            out << ch;
            ++cnt;
            lock.unlock();
            cv.notify_all();
        }
    }
    
    void read()
    {
        char ch;
        while (true)
        {
            unique_lock<mutex> lock(mu);
            cv.wait(lock, [&] { return cnt>0; });
            in >> ch;
            cout << "cout:" << ch << endl;
            --cnt;
        }
    }
    
    int main()
    {
        cnt = in.tellg();//文件流对象有两个可用于随机文件访问的成员函数:tellp 和 tellg
                         //tellp 用于返回写入位置,tellg 则用于返回读取位置
        thread w(write);
        thread r0(read);
        thread r1(read);
        thread r2(read);
    
        w.join();
        r0.join();
        r1.join();
        r2.join();
        in.close();
        out.close();
        return 0;
    }

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

    #include <thread>
    #include <mutex>
    #include <condition_variable>
    #include <fstream>
    #include <queue>
    using namespace std;
    
    template<typename T>
    class thread_safe_queue {
    private:
        mutex mu;
        condition_variable cv;
        queue<T> que;
    
    public:
        thread_safe_queue() = default;
        ~thread_safe_queue() = default;
        thread_safe_queue(const queue<T>& q) :que(q) {}
        thread_safe_queue(const thread_safe_queue& tsq){
            std::unique_lock<mutex> lock(mu);
            que = tsq;
        }
    
        void push(const T &data)
        {
            std::unique_lock<mutex> lock(mu);
            que.push(data);
            cout << "push:" << data << endl;
            lock.unlock();
            cv.notify_all();
        }
    
        T pop(void)
        {
            std::unique_lock<mutex> lock(mu);
            cv.wait(lock, [&] {return !que.empty(); });
            T value = que.front();
            que.pop();
            return value;
        }
    
        bool empty(void)
        {
            std::unique_lock<mutex> lock(mu);
            return que.empty();
        }
    };
    
    thread_safe_queue<int> q;
    mutex mu;
    
    int main()
    {
        auto push_value = [&] {
            for (int i=0;i<100;++i)
            {
                q.push(i);
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
                //this_thread::yield(); //降低cpu使用率,死循环cpu占用很高的
            }
        };
        auto pop_value = [&] {
            while (true)
            {
                while (!q.empty())
                {
                    std::unique_lock<mutex> lock(mu);
                    cout <<"pop:"<< q.pop() << endl;
                }
            }
        };
        thread pushT(push_value);
        thread popT0(pop_value);
        thread popT1(pop_value);
    
        pushT.join();
        popT0.join();
        popT1.join();
        return 0;
    }

    总结:

    通常来说使用sleep。

     std::this_thread::sleep_for(std::chrono::milliseconds(1));
    this_thread::yield(); //降低cpu使用率,死循环cpu占用很高的

    两种效果不一样:

     

    展开全文
  • 多线程练习题目.doc

    2021-09-28 11:04:41
    多线程练习题目.doc
  • 多线程练习题卷.pdf

    2021-10-24 03:58:06
    多线程练习题卷.pdf
  • 多线程练习源码
  • 本关任务:利用多线程相关知识控制三个线程,依照先后顺序顺序输出。 相关知识(略) 编程要求 请仔细阅读右侧代码,在 Begin-End 区域内进行代码补充,使线程依照先后顺序依次输出JavaThread+线程名。 提示:我们...
  • Java多线程练习

    热门讨论 2008-11-21 09:00:27
    这是对Java多线程的一些相关练习题 包括选择 填空 简答 编程等题型
  • 多线程练习

    千次阅读 2019-05-14 15:28:32
    多线程练习题 1.写一段简单的程序,启动两个线程交替打印1–100 题目分析: 只打印1—100,为了保证数据的同步必须加锁,同时又需要线程交替打印,则需要线程间的通信。 解题思想: 启动两个线程A和线程B,两个...
  • Socket多线程练习

    2019-03-16 01:09:57
    NULL 博文链接:https://lucane.iteye.com/blog/379796
  • Java多线程练习题.docx

    2020-04-05 11:13:51
    Java多线程习题 一选择题 什么原因可导致线程停止执行( ) 线程调用了wait)方法 线程调用了yield)方法 线程调用了pause)方法 线程调用了sleep)方法 哪个方法是实现Runnable接口所需的( ) A. wait) Brun) Cstop) D...
  • python 多线程练习题---四个线程同步打印a b c d1. 题目描述有四个线程,每个线程只打印一个字符,这四个字符分别是 a b c d ,现在要求你做到四个线程顺序打印 a b c d ,且每个线程都打印10次2. 思路分析假设1 线程...
  • Java高级特性 - 多线程练习

    千次阅读 2021-01-17 11:29:53
    本关任务:利用多线程相关知识控制三个线程,依照先后顺序顺序输出。 相关知识(略) 编程要求 请仔细阅读右侧代码,在 Begin-End 区域内进行代码补充,使线程依照先后顺序依次输出JavaThread+线程名。 提示:我们...
  • pthread_piano-DE1-SOC 在钢琴上将中级C范围合成为多线程并与音频CODEC练习一起使用。 该程序有两个线程,一个线程侦听键盘输入以模拟钢琴键,另一个线程从按下的键计算样本。 tone_volume是互斥变量,并使用衰减...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 60,564
精华内容 24,225
关键字:

多线程练习