Difference between revisions of "CSC352 Homework 3 2013"

From dftwiki3
Jump to: navigation, search
Line 44: Line 44:
 
   gcc -o producer1 producer1.c
 
   gcc -o producer1 producer1.c
 
   javac Consumer1.java
 
   javac Consumer1.java
 +
 +
  mkfifo temp
 +
 
   java Consumer1 &          # run in the background
 
   java Consumer1 &          # run in the background
 
   ./producer1
 
   ./producer1
Line 110: Line 113:
 
   gcc -o producer1 producer1.c
 
   gcc -o producer1 producer1.c
 
   javac Consumer1.java
 
   javac Consumer1.java
 +
 +
  mkfifo temp
 +
 
   java Consumer1 &          # run in the background
 
   java Consumer1 &          # run in the background
 
   ./producer1
 
   ./producer1
Line 171: Line 177:
 
* Run them both, starting with the consumer, since it is waiting on the producer to actually process the data, and then with the producer.  Adding the '''&''' symbol at the end of the line starting the java program runs it in the background.  It is important to do so, otherwise you would be stuck waiting for Consumer1 to be done before being able to type a new command, but Consumer1 cannot be done until you have started producer1...
 
* Run them both, starting with the consumer, since it is waiting on the producer to actually process the data, and then with the producer.  Adding the '''&''' symbol at the end of the line starting the java program runs it in the background.  It is important to do so, otherwise you would be stuck waiting for Consumer1 to be done before being able to type a new command, but Consumer1 cannot be done until you have started producer1...
  
 +
        mkfifo temp          # ''tell Linux/Mac OSX that temp is a temporary file used as a pipe/fifo between two apps
 
         java Consumer1  &
 
         java Consumer1  &
 
         ./producer1
 
         ./producer1

Revision as of 13:45, 9 October 2013

--D. Thiebaut (talk) 14:38, 9 October 2013 (EDT)



This assignment is due on 10/22/13 during class. You can work in pairs on this if you desire, but only if you follow the pair-programming model, where two programmers work together at one computer.


The Idea


The idea is to start programming for our collage app. At some point, it is very likely that we will want to have some Linux machines run some C/MPI programs in the background to scale images on the fly, or perform some time consuming task, and there will be a Processing/Java program that will be in charge of interacting with the user(s) and display the collage.

So we need to figure out how to interface Java and C programs. This is the purpose of this assignment.

Interfacing C and Java


One way to exchange data between the C program (we'll call it the producer) and the Java program (the consumer) is to use a Linux fifo. Please read the information about mkfifo in Wikipedia. Mkfifo allows your programs to be written as if they were exchanging data by having the producer write the data to a file, and the consumer read the data from the same file. Mkfifo makes the file temporary and erases it when the exchange is done. That simple!

Good Tutorial on the Subject


The tutorial "How to connect a C/C++ process to a Java application (link) is very good. Please give it a quick reading. It will give you an idea of what we have to do in C and Java for the two to talk to each other. Below I created a simpler version of the Producer and Consumer for you to play with.

A Producer in C: producer1.c


/*
producer1.c
D. Thiebaut
This program generates N random numbers in an array,
sorts them, and sends them out to a java application
through a Linux Fifo.  See the Linux command mkfifo
for more information.

The java application is called consumer1.java.
To compile and run both:

   gcc -o producer1 producer1.c
   javac Consumer1.java
 
   mkfifo temp
 
   java Consumer1 &           # run in the background
   ./producer1

This example is inspired by the good tutorial at this URL: 
http://research.engineering.wustl.edu/~beardj/CtoJava.html
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <stdint.h>

#define N 100

// -----------------------------------------------------
// comp(): a comparator function to compare to different
// integers
int comp (const void * elem1, const void * elem2) {
  int f = *( (int*) elem1 ); // typecast elem1 to become a pointer to an int,
  int s = *( (int*) elem2 ); // then dereference elem1 to get the int it's pointing to
  if (f > s) return  1;
  if (f < s) return -1;
  return 0;
}

// ===================== M A I N =======================
int main(int argc, const char** argv){
  int i, array[N];
  const char* outFile = "temp";

  //--- seed random number generator ---
  srand ( 123 );
  for ( i=0; i<N; i++ )
    array[i]  = rand() % 1000; // numbers in [0,1000[

  //--- sort the N ints in the array "array",  ---
  //--- using comparator comp()                ---
  qsort( array, N, sizeof( int ), comp );

  //--- open fifo for writing ---
  FILE *fp_out = fopen(outFile,"w");

  //--- output dimension N, then all N ints ---
  fprintf( fp_out, "%d\n", N );
  for ( i=0; i<N; i++ )
    fprintf( fp_out, "%d\n", array[i] );

   //--- close output fifo ---
   fclose(fp_out);
   return( 0 ); // success
}


The Java Consumer: Consumer1.java


/*
  Consumer1.java
  D. Thiebaut
  the consumer part of the producer-consumer example made of 
  producer1.c and consumer1.java

  To compile and run:
   gcc -o producer1 producer1.c
   javac Consumer1.java
 
   mkfifo temp
 
   java Consumer1 &           # run in the background
   ./producer1

  Example inspired by the good tutorial at 
  http://research.engineering.wustl.edu/~beardj/CtoJava.html
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.FileReader;
import java.util.ArrayList;

public class Consumer1{    
    //--- the external FIFO we'll use.  It's a file ---
    //--- that Linux will manage as a FIFO for us   ---
    private static final String FIFO = "temp"; 
    
    public static void main(String[] args){
	BufferedReader in = null;
	ArrayList<Integer> array = new ArrayList<Integer>();
	int N = 0, count = 0;
	boolean firstLine = true;

	try{
	    in = new BufferedReader(new FileReader(FIFO));
	    while ( in.ready() ) {
		String line = in.readLine().trim();
		int x = Integer.parseInt( line );
		if ( firstLine ) {
		    N = x;
		    firstLine = false;
		}
		else {
		    array.add( x );
		    count++;
		}
	    }
	    in.close();
	} catch( IOException ex ){
	    System.err.println( "IO Exception at buffered read!!" );
	    System.exit( -1 );
	}
	
	//--- we're done.  Display what we received
	System.out.println( "Expected " + N + " ints, received " + count + " ints");
	for ( int x: array )
	    System.out.print( x + " " );
	System.out.println( "\n\n" );
   }
}

Compile and Run

  • This should work on your MacBook, as mkfifo should be part of OS X, but if you run into trouble, run this on Beowulf.
  • Create the C and Java programs listed above.
  • Compile both:
      gcc -o producer1  producer1.c
      javac Consumer1.java
  • Run them both, starting with the consumer, since it is waiting on the producer to actually process the data, and then with the producer. Adding the & symbol at the end of the line starting the java program runs it in the background. It is important to do so, otherwise you would be stuck waiting for Consumer1 to be done before being able to type a new command, but Consumer1 cannot be done until you have started producer1...
       mkfifo temp           # tell Linux/Mac OSX that temp is a temporary file used as a pipe/fifo between two apps
       java Consumer1  &
       ./producer1