两个线程交替打印信息

看见一个关于两个线程交替打印信息的题目,题目大概是

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

写了两个版本,一个是用了mutex,不用条件变量;另外一个是用条件变量。

第一个,不用条件变量

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <pthread.h>
 4
 5
 6
 7 const int LOOP_2 = 2;
 8 const int LOOP_5 = 5;
 9 int loop_count_slave = 10;
10 int loop_count_main = 10;
11
12 enum bool { FALSE = 0,TRUE =1};
13 enum bool slave_can_print = TRUE;
14 enum bool main_can_print = FALSE;
15
16 pthread_cond_t cond_slave = PTHREAD_COND_INITIALIZER;
17 pthread_cond_t cond_main =  PTHREAD_COND_INITIALIZER;
18
19
20 pthread_mutex_t mutex_slave = PTHREAD_MUTEX_INITIALIZER;
21 pthread_mutex_t mutex_main = PTHREAD_MUTEX_INITIALIZER;
22
23 void* thread_fun(void* arg);
24 void printf_msg(int type);
25
26 int main(int argc, char* argv[])
27 {
28     pthread_t tid;
29     int ret;
30     ret = pthread_create(&tid,NULL,thread_fun,NULL);
31     if( ret != 0 )
32     {
33         strerror(ret);
34     }
35     while(loop_count_main > 0)
36     {
37         pthread_mutex_lock(&mutex_main);
38         if(main_can_print)
39         {
40             printf_msg(1);
41             loop_count_main -- ;
42             pthread_mutex_lock(&mutex_slave);
43             slave_can_print = TRUE;
44             pthread_mutex_unlock(&mutex_slave);
45             main_can_print = FALSE;
46         }
47         pthread_mutex_unlock(&mutex_main);
48     }
49
50
51 }
52 void* thread_fun(void* arg)
53 {
54     while(loop_count_slave > 0)
55     {
56         pthread_mutex_lock(&mutex_slave);
57         if(slave_can_print)
58         {
59             printf_msg(2);
60             loop_count_slave -- ;
61             slave_can_print = FALSE;
62             pthread_mutex_lock(&mutex_main);
63             main_can_print = TRUE;
64             pthread_mutex_unlock(&mutex_main);
65         }
66         pthread_mutex_unlock(&mutex_slave);
67     }
68     return NULL;
69 }
70 void printf_msg(int type)
71 {
72     if(type == 1)
73     {
74         int i = 0;
75         for(; i < LOOP_5; i++)
76         {
77             printf("from master \n");
78
79         }
80     }
81     else if(type == 2)
82     {
83         int i = 0;
84         for(; i < LOOP_2; i++)
85         {
86             printf("from slave thread\n");
87         }
88     }
89 }

第二个,使用条件变量

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <pthread.h>
 4
 5
 6
 7 const int LOOP_2 = 2;
 8 const int LOOP_5 = 5;
 9 int loop_count_slave = 10;
10 int loop_count_main = 10;
11
12 enum bool { FALSE = 0,TRUE =1};
13 enum bool slave_can_print = TRUE;
14 enum bool main_can_print = FALSE;
15
16 pthread_cond_t cond_slave = PTHREAD_COND_INITIALIZER;
17 pthread_cond_t cond_main =  PTHREAD_COND_INITIALIZER;
18
19
20 pthread_mutex_t mutex_slave = PTHREAD_MUTEX_INITIALIZER;
21 pthread_mutex_t mutex_main = PTHREAD_MUTEX_INITIALIZER;
22
23 void* thread_fun(void* arg);
24 void printf_msg(int type);
25
26 int main(int argc, char* argv[])
27 {
28     pthread_t tid;
29     int ret;
30     ret = pthread_create(&tid,NULL,thread_fun,NULL);
31     if( ret != 0 )
32     {
33         strerror(ret);
34     }
35     while(loop_count_main > 0)
36     {
37         pthread_mutex_lock(&mutex_main);
38         if(main_can_print)
39         {
40             printf_msg(1);
41             loop_count_main -- ;
42             main_can_print = FALSE ;
43             pthread_mutex_lock(&mutex_slave);
44             slave_can_print = TRUE;
45             pthread_mutex_unlock(&mutex_slave);
46             pthread_cond_signal(&cond_slave);
47         }
48         else
49         {
50             pthread_cond_wait(&cond_main,&mutex_main);
51         }
52         pthread_mutex_unlock(&mutex_main);
53     }
54
55 }
56 void* thread_fun(void* arg)
57 {
58     while(loop_count_slave > 0)
59     {
60         pthread_mutex_lock(&mutex_slave);
61         if(slave_can_print)
62         {
63             printf_msg(2);
64             loop_count_slave -- ;
65             slave_can_print = FALSE;
66             pthread_mutex_lock(&mutex_main);
67             main_can_print = TRUE;
68             pthread_mutex_unlock(&mutex_main);
69             pthread_cond_signal(&cond_main);
70         }
71         else
72         {
73             pthread_cond_wait(&cond_slave,&mutex_slave);
74         }
75         pthread_mutex_unlock(&mutex_slave);
76     }
77
78     return NULL;
79 }
80 void printf_msg(int type)
81 {
82     if(type == 1)
83     {
84         int i = 0;
85         for(; i < LOOP_5; i++)
86         {
87             printf("from master \n");
88
89         }
90     }
91     else if(type == 2)
92     {
93         int i = 0;
94         for(; i < LOOP_2; i++)
95         {
96             printf("from slave thread\n");
97         }
98     }
99 }

比较两次执行,使用条件变量大概耗时只有0.002s,不使用条件变量大概0.2s,性能相差巨大。

原因在于不使用条件变量时,一直在忙循环,测试条件。

时间: 2024-11-14 17:40:23

两个线程交替打印信息的相关文章

经典面试题——两个线程交替打印奇数和偶数

前提 今天下班时候和同事聊天偶然听到面试题“两个线程交替打印奇数和偶数”的实现,这里做一个复盘. 复盘 场景一:线程A打印奇数,线程B打印偶数,线程A和线程B交替打印,使用对象监视器实现. 场景二:线程A打印奇数,线程B打印偶数,线程A和线程B交替打印,使用JDK提供的并发类库实现. 这两个场景中,场景一是一种比较古老的同步方式,本质由JVM实现:场景二是JDK1.5引入JUC包之后简化了并发编程的前提下的更简便的实现.下面针对两个场景做对应的实现. 场景一 场景一中,线程A和线程B交替打印奇数

两个线程交替打印1-99

参考https://github.com/crossoverJie/JCSprout/blob/master/src/main/java/com/crossoverjie/actual/TwoThread.java从线程方面实现交替打印. public class Test { volatile boolean isEven = false; @org.junit.Test public void testfda() throws InterruptedException { Thread a

经典笔试题:两个线程交替打印奇偶数

一.采用对象的wait() notify()方法实现 package com.gaopeng.programming; import java.util.concurrent.TimeUnit; /** * 经典笔试题:交替打印奇偶数 采用对象的wait() notify()方法实现 * * @author gaopeng * */ public class OddEvenThread { private static volatile Integer counter = 0; public s

两个线程交替打印奇数和偶数

public class ThreadTest { public static void main(String[] args) { Thread evenThread = new Thread(new PrintEven(),"打印奇数"); Thread oddThread = new Thread(new PrintOdd(),"打印偶数"); evenThread.start(); oddThread.start(); } } class Count{ pu

控制两个线程交替打印

package datatype; public class demo { static final Object object = new Object(); public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { for (int i = 1; i < 51; i++) { System.out.print(i); if (i

头条面试题之实现两个线程轮流打印字符串

在面试头条的时候,有一个很有意思的题目,利用两个线程交替打印一个字符串,这里主要就是对多线程中wait/notify的应用,特此记录. 对于wait()和notify()的理解,还是要从jdk官方文档中开始,在Object类方法中有: void notify() Wakes up a single thread that is waiting on this object’s monitor. 译:唤醒在此对象监视器上等待的单个线程 void notifyAll() Wakes up all t

Java多线程通信之两个线程分别打印AB各10次

一道经典的面试题目:两个线程,分别打印AB,其中线程A打印A,线程B打印B,各打印10次,使之出现ABABABABA.. 的效果 1 package com.shangshe.path; 2 3 public class ThreadAB { 4 5 /** 6 * @param args 7 */ 8 public static void main(String[] args) { 9 10 final Print business = new Print(); 11 12 new Threa

Java 两线程交替打印奇偶数(一)

使用synchronized 及 Object对象的wait()和notifyAll()方法, Code如下 package com.shiwei.thread; public class OddEvenRunable { private static Object lock = new Object(); public static void main(String[] args) { PrintNumber pOdd = new PrintNumber(true, lock); PrintN

记录一次回客科技有关线程的笔试题,三个线程加法和一个线程减法 ,延申的两个线程交替执行

今天去了回客科技 笔试了一波.很遗憾啊,脑袋有思路 但是还没到手写代码很熟练的程度,基本功不到位. 第一道:线程的题:三个线程 +1 一个线程 -1 运算 . 看到网上还有四个线程的,两个加法计算,两个减法运算.基本的思路都是一样的 ,注意看同步处理. 下面贴出代码实现: public class AddTest { private static int i; private static Object object = new Object(); public static void main