精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-01
最后修改:2011-01-26
引用 有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC…
引申了一下: 有n个线程,ID为0...n-1,在屏幕上循环打印m次012..n-1 用 c/pthread 实现 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <pthread.h> #define GROUP_COUNT 100 #define GROUP_SIZE 4 typedef struct { pthread_mutex_t mutex; pthread_cond_t cond; int index; } syn_obj_t; syn_obj_t syn_obj = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0}; typedef struct { int flag; } elem_t; void * thread_routine(void *arg); int main(int argc, char** argv) { elem_t elems[GROUP_SIZE]; pthread_t pds[GROUP_SIZE]; int i; printf("syn_obj.index = %d\n", syn_obj.index); for (i = 0; i < GROUP_SIZE; i++) { elems[i].flag = i; if ( (pthread_create(&pds[i], NULL, thread_routine, &elems[i])) != 0 ) { perror("pthread create"); exit(-1); } } for (i = 0; i < GROUP_SIZE; i++) { pthread_join(pds[i], NULL); } pthread_mutex_destroy(&syn_obj.mutex); pthread_cond_destroy(&syn_obj.cond); printf("\nsyn_obj.index = %d\n", syn_obj.index); return 0; } void * thread_routine(void *arg) { elem_t *elem = (elem_t *)arg; int i; for (i = 0; i < GROUP_COUNT; i++) { pthread_mutex_lock(&syn_obj.mutex); while ( (syn_obj.index % GROUP_SIZE) != elem->flag ) { pthread_cond_wait(&syn_obj.cond, &syn_obj.mutex); } printf("%d", elem->flag); if ( 0 == (syn_obj.index+1) % GROUP_SIZE ) { printf("\t"); } syn_obj.index++; pthread_cond_broadcast(&syn_obj.cond); // may be cause deadlock // pthread_cond_signal(&syn_obj.cond); pthread_mutex_unlock(&syn_obj.mutex); // sleep(1); } return NULL; } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-12-04
LZ分享得不错哈~
|
|
返回顶楼 | |
发表时间:2009-12-05
最后修改:2009-12-05
贴一个Java的,实现可能和楼主的有些差别,输出A、B、C分别使用三个不同的线程类。不过原理都是一样,实现线程的顺序调度。判断条件,不满足的话,等待;接到通知以后,重新判断。
public class SequenceWork { private static Boolean[] abc = {false, false, true}; public static void main(String[] args) { ThreadA a = new ThreadA(); a.start(); ThreadB b = new ThreadB(); b.start(); ThreadC c = new ThreadC(); c.start(); } static class ThreadA extends Thread { public void run() { while (true) { synchronized (abc) { if (abc[2]) { System.out.print("A"); abc[0] = true; abc[2] = false; abc.notifyAll(); } else { try { abc.wait(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } } } static class ThreadB extends Thread { public void run() { while (true) { synchronized (abc) { if (abc[0]) { System.out.print("B"); abc[1] = true; abc[0] = false; abc.notifyAll(); } else { try { abc.wait(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } } } static class ThreadC extends Thread { public void run() { while (true) { synchronized (abc) { if (abc[1]) { System.out.println("C"); abc[2] = true; abc[1] = false; abc.notifyAll(); } else { try { abc.wait(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } } } } |
|
返回顶楼 | |
发表时间:2009-12-05
shelocks 写道 贴一个Java的,实现可能和楼主的有些差别,输出A、B、C分别使用三个不同的线程类。不过原理都是一样,实现线程的顺序调度。判断条件,不满足的话,等待;接到通知以后,重新判断。
public class SequenceWork { private static Boolean[] abc = {false, false, true}; public static void main(String[] args) { ThreadA a = new ThreadA(); a.start(); ThreadB b = new ThreadB(); b.start(); ThreadC c = new ThreadC(); c.start(); } static class ThreadA extends Thread { public void run() { while (true) { synchronized (abc) { if (abc[2]) { System.out.print("A"); abc[0] = true; abc[2] = false; abc.notifyAll(); } else { try { abc.wait(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } } } static class ThreadB extends Thread { public void run() { while (true) { synchronized (abc) { if (abc[0]) { System.out.print("B"); abc[1] = true; abc[0] = false; abc.notifyAll(); } else { try { abc.wait(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } } } static class ThreadC extends Thread { public void run() { while (true) { synchronized (abc) { if (abc[1]) { System.out.println("C"); abc[2] = true; abc[1] = false; abc.notifyAll(); } else { try { abc.wait(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } } } } 楼上的解法正点! |
|
返回顶楼 | |
发表时间:2009-12-05
最后修改:2009-12-05
另外一个版本。。。
public class SequenceWork { private static final int GROUP_SIZE=10; private static final int RUN_COUNT=4; private static boolean[] res = new boolean[GROUP_SIZE]; public static void main(String[] args) { res[0]=true; for(int i=0;i<GROUP_SIZE;i++){ new MyThread(i).start(); } } static class MyThread extends Thread { private Integer id; private String name; public MyThread(){} public MyThread(Integer id){ this.id=id; this.name=id+" "; } public void run() { int count=0; if(id==GROUP_SIZE-1){ this.name+="\n"; } while (true) { synchronized (res) { if (res[id]) { System.out.print(name); ++count; res[(id+1)%GROUP_SIZE] = true; res[id] = false; res.notifyAll(); if(count==RUN_COUNT){ return; } } else { try { res.wait(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } } } } |
|
返回顶楼 | |
发表时间:2009-12-06
最后修改:2009-12-06
jeye.bow 写道 引用 有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC…
引申了一下: 有n个线程,ID为0...n-1,在屏幕上循环打印m次012..n-1 用 c/pthread 实现 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <pthread.h> /*......*/ void * thread_routine(void *arg) { elem_t *elem = (elem_t *)arg; int i; for (i = 0; i < GROUP_COUNT; i++) { pthread_mutex_lock(&syn_obj.mutex); while ( (syn_obj.index % GROUP_SIZE) != elem->flag ) { pthread_cond_wait(&syn_obj.cond, &syn_obj.mutex); } printf("%d", elem->flag); if ( 0 == (syn_obj.index+1) % GROUP_SIZE ) { printf("\t"); } syn_obj.index++; pthread_cond_broadcast(&syn_obj.cond); /*A*/ // may be cause deadlock // pthread_cond_signal(&syn_obj.cond); pthread_mutex_unlock(&syn_obj.mutex); /*B*/ // sleep(1); } return NULL; } 写的不错,是校园招聘吗,如果现场能写成这样不错了 不过 这里的 A 和 B 需要掉个位置 因为pthread_cond_wait 不够原子 |
|
返回顶楼 | |
发表时间:2009-12-06
easonfans 写道 shelocks 写道 贴一个Java的,实现可能和楼主的有些差别,输出A、B、C分别使用三个不同的线程类。不过原理都是一样,实现线程的顺序调度。判断条件,不满足的话,等待;接到通知以后,重新判断。
public class SequenceWork { private static Boolean[] abc = {false, false, true}; public static void main(String[] args) { ThreadA a = new ThreadA(); a.start(); ThreadB b = new ThreadB(); b.start(); ThreadC c = new ThreadC(); c.start(); } static class ThreadA extends Thread { public void run() { while (true) { synchronized (abc) { if (abc[2]) { System.out.print("A"); abc[0] = true; abc[2] = false; abc.notifyAll(); } else { try { abc.wait(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } } } //。。。。。。。。。。。。。 楼上的解法正点! 万一是线程池呢。。。。。。你的代码就吓死人了哈哈 |
|
返回顶楼 | |
发表时间:2009-12-06
最后修改:2009-12-06
sunzixun 写道 easonfans 写道 shelocks 写道 贴一个Java的,实现可能和楼主的有些差别,输出A、B、C分别使用三个不同的线程类。不过原理都是一样,实现线程的顺序调度。判断条件,不满足的话,等待;接到通知以后,重新判断。
public class SequenceWork { private static Boolean[] abc = {false, false, true}; public static void main(String[] args) { ThreadA a = new ThreadA(); a.start(); ThreadB b = new ThreadB(); b.start(); ThreadC c = new ThreadC(); c.start(); } static class ThreadA extends Thread { public void run() { while (true) { synchronized (abc) { if (abc[2]) { System.out.print("A"); abc[0] = true; abc[2] = false; abc.notifyAll(); } else { try { abc.wait(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } } } //。。。。。。。。。。。。。 楼上的解法正点! 万一是线程池呢。。。。。。你的代码就吓死人了哈哈 输出A、B、C是三个不同的任务,他们之间要以一种顺序化的顺序调度,而不是简单的在一个线程里输出不同的标志位。上面的示例代码代码是extends thread,你完全可以把它实现为Runnable。跟线程池有什么关系。 |
|
返回顶楼 | |
发表时间:2009-12-06
我参照了下兄弟们写的,用的是JAVA5.0的ReentrantLock也写了一个:
大家一起一为鉴赏一下 调用类:FuLockThreadTest //用于线程ABC的调用实现 public class FuLockThreadTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // 加锁实现 new Thread(new FuLockThread(0), "A").start();// 注意线程命名 new Thread(new FuLockThread(1), "B").start(); new Thread(new FuLockThread(2), "C").start(); } } 线程类:FuLockThread //用ReentrantLock加锁机制实现,注意在finally里面实现解锁 import java.io.IOException; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class FuLockThread extends Thread { private int id; private static int count = 0;// 活学活用static类型 private int pcount; private boolean mark = true; private ReentrantLock lock; private Condition condition; public FuLockThread(int id) { this.id = id; lock = new ReentrantLock(); condition = lock.newCondition(); } @Override public void run() { // TODO Auto-generated method stub // 当前的count计数为id值,则进行输出 // 加锁实现 lock.lock(); try {// 加锁实现 while (mark) { if (count % 3 == id) { System.out.print(Thread.currentThread().getName()); count++; pcount++; condition.signalAll(); if (pcount == 10) mark = false; } } } finally { if (count % 3 != id) { try { condition.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else lock.unlock(); } } } |
|
返回顶楼 | |
发表时间:2009-12-06
一种没有使用并发包的实现。遇到一个问题,lock对象如果直接用Integer会异常,封装成Lock类就可以了。
public class SequenceTask { private static volatile Lock lock = new Lock(); private static String[] infos = { "A", "B", "C" }; public static void main(String[] args) { for (int i = 0; i < infos.length; i++) { Thread thread = new Thread(new PrintTask(i)); thread.start(); } } static class Lock { private int flag = 0; public int getFlag() { return flag; } public void setFlag(int flag) { this.flag = flag; } } static class PrintTask implements Runnable { private int id; public PrintTask(int id) { this.id = id; } public void run() { while (true) { synchronized (lock) { if (lock.getFlag() == id) { System.out.print(infos[id]); lock.setFlag((id + 1) % infos.length); lock.notifyAll(); } else { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } } |
|
返回顶楼 | |