Problem Producenta i Konsumeta

0

Witam,

Ma problem z programem, tzn. Dla komputera z jednym prockiem wykonuje poprawnie algorytm, działa tak jak chce, ale jak zapuszczam program na komputerze dwuprocesorowym to zaczynają sie schody.

Wynik:

Dla jednego Procesora: (+ Prodeucent, -Konusment)
+

Dla dwóch:
+
+

Wiecie może Panowie jak rozwiać ten problem ?

0

No kodu pokazales tyle ze nie mozna sie dokopac do sedna problemu.

0

Uzywasz w ogole jakiejs synchronizacji, i masz ja zle zrobiona i pytasz o pomoc, czy w ogole nie masz synchronizacji miedzy watkami?

0

A zrobiłęm już, zbyt szybko się podaje. Przepraszam za kłopot. I Dziękuje!

0

Witam, Mój Linux mnie zaksoczył. W czwartek działał mi programik, a już dziś nie działa. Jak to się stało, no kurcze niewiem. Jeśli chodzi o kod to prosze:

public class ChancyDrop implements Drop {

     int value;
     static Object w=new Object();

     boolean pelny=false;
   	
     
     public int take() throws InterruptedException
     { 
      synchronized(w)
      {
      
           while(pelny)
           {
            w.wait()
	    
           }
           pelny=true;
           w.notify();
           return value;
      }
     }
     
     public void put(int value) throws InterruptedException
     {
      synchronized(w)
      {
           while(!pelny)
           {
	    w.wait()
            
           }
           pelny=false;
           this.value = value;
           w.notify();
      }
     } 
}
public class Main {

    public static void main(String args[]) throws InterruptedException {
		Drop d = new ChancyDrop();
		//Drop t = new ChancyDrop();
	//	Drop d = new SafeDrop();
	Producer p1 = new Producer(d);
	Producer p2 = new Producer(d);
	Consumer c1 = new Consumer(d);
	Consumer c2 = new Consumer(d);
	//p1.setPriority(5);
	//c1.setPriority(4);
	//int a=1;
	
	//if(a%2==1)
	//{
	p1.start();
	//a++;	
	//}
	p2.start();
	//p2.setPriority(3);
	//if(a%2==0)
	//{
	c1.start();
	//a++;
	//}
	
	c2.start();
	//c2.setPriority(2);

	p1.join();
	p2.join();
	c1.join();
	c2.join();
	
	/*if (p1.getSum() + p2.getSum() == c1.getSum() + c2.getSum())
	    System.out.println("Validation failed!");*/
    }
}

Program na jednordzeniowym procesorze śmiga, tutaj jest kłopot, ponieważ są dwa rdzenie. Może jest tak ze java jeszcze nie jest nauczona, obsługi wątków w sposób dobry na procesorach X2 ??

0
  1. chyba masz blad w ChancyDrop
public class ChancyDrop {

	int value;

	boolean pelny = false;

	public synchronized int take() {
		while (!pelny) {
			try {
				notifyAll();
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		pelny = false;
		notifyAll();
		return value;
	}

	public synchronized void put(int value) {
		while (pelny) {
			try {
				notifyAll();
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		pelny = true;
		this.value = value;
		notifyAll();
	}
}
  1. to, że w konsoli widzisz ++--++-- zamiast +-+-+-+- itd to nie jest problem wielu rdzeni, procesorow czy zle napisanego programu. Jest to efekt braku synchronizacji pomiedzy pobraniem/wstawieniem a wypisaniem +/-
put(i);
sysout("+");
.....
get();
sysout("-");

jak widac na powyzszym listingu moze sie zdarzyć sytuacja:

  • producent wstawia,
  • konsument pobiera,
  • wypisany jest znak "-",
  • drugi producent wstawia
  • drugi konsument pobiera,
  • wypisany jest znak "-"
  • wypisany jest znak "+"
  • wypisany jest znak "+"
0

Dzięki za szybką odpowiedz, to w takim razie jak zsynchronizować te bloki by był +-+-+-+- ??

0

wrzuc sysout do metody get() oraz put() (na koniec - zaraz przed returnem)

0
krzyzy napisał(a)

wrzuc sysout do metody get() oraz put() (na koniec - zaraz przed returnem)

Właśnie przed chwilą na to wpadłem, i działa. Podziękował. Chociaż jedna próba wypisze żle, a tak śmiga.

public class ChancyDrop implements Drop{

        int value;

        boolean pelny = false;

        public synchronized int take() {
                while (pelny == false) {
                        try {
                                notify();
                                wait();
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
                pelny = false;
                notify();
                System.out.println("take");
		return value;
		
        }

        public synchronized void put(int value) {
                while (pelny == true) {
                        try {
                                notify();
                                wait();
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
                pelny = true;
                this.value = value;
                notify();
		System.out.println("put");
        }
}
0

I tak chyba jeszcze wait() będe musiał rzucić, ponieważ przy 4 wątkach sypie się nie miłosiernie.

0

Nie analizwoalem doglebnie kodu, ale moze zdradzisz dlaczego maz i w put i w take w bloku synchronizowanym sekwencje 'notify - wait'?

0

Nie analizwoalem doglebnie kodu, ale moze zdradzisz dlaczego maz i w put i w take w bloku synchronizowanym sekwencje 'notify - wait'?
Z mojej strony to proste niedopatrzenie.

dlaczego zamieniles notifyAll() an notify()? czy nie jest tak ze konsument moze wybudzic konsumenta (obaj producenci spia) a ten od razu zrobi wait() i doprowadz to do zakleszczenia>

1 użytkowników online, w tym zalogowanych: 0, gości: 1