Search code examples
coutputputtywinscp

Using WinSCP/Putty and getting nonsense output file after running main.c


I have 3 files, a main.c, a makefile, and a h2o.h. I am using WinSCP for transferring files to an SSH, and using Putty for running the makefile. Everything compiles and outputs to a file I've called main.txt. However, that output is a bunch of nonsense characters.

For example: ÿÿ1íI‰Ñ^H‰âHƒäðPTIÇÀà@

When it should output something like:

Thread 6 Oxygen has entered, waiting_H: 0, waiting_H: 0

Thread 7 Hydrogen has entered, waiting_H: 0, waiting_H: 0

Is there some sort of unencryption I have to write in to make my output readable?

I have included my code for all three files below.

Thanks

h2o.h:

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 10
#endif

extern const unsigned int RAND_RANGE;

typedef struct _thread_data_t {
    int tid;//thread id
    int waiting_O;//waiting Oxygen
    int waiting_H;//waiting Hydrogen

} thread_data_t;

makefile:

all: main.c h2o.h
    gcc -Wall -pthread -std=c99 -o main.txt main.c
    chmod 755 main
clean:
    -rm main

main.c

#include "h2o.h"

//the range of return values for getRandom() function is
//[-RAND_RANGE/2, RAND_RANGE/2]
const unsigned int RAND_RANGE = RAND_MAX>>10;

int waiting_O = 0;//number of oxygen waiting
int waiting_H = 0;//number of hydrogen waiting
sem_t a, b, mutex;
time_t t;
char debug = 0;//used to debug

int getRand();//returns a random int
void *oxygen(void *arg);//thread function for oxygen
void *hydrogen(void *arg);//thread function for hydrogen
void semwait(sem_t *sem);//error-checked semaphore wait
void semsignal(sem_t *sem);//error-checked semaphore signal

int main(int argc, char const *argv[]) {
    pthread_t threads[NUM_THREADS];
    thread_data_t thread_data[NUM_THREADS];
    int errorCheck;//used to error check thread creation

    //seed the random number generator
    srand((unsigned int)time(&t));

    //initialize semaphores
    if (sem_init(&mutex, 0, (unsigned int)1) < 0
        || sem_init(&a, 0, (unsigned int)0) < 0
        || sem_init(&b, 0, (unsigned int)0) < 0) {
        perror("sem_init");
        exit(EXIT_FAILURE);
    }

    if (debug) {
        /*
        * debug mode:
        *   oxygen 1
        *   hydrogen 1
        *   hydrogen 1 
        */
        thread_data[0].tid = 0;
        thread_data[0].waiting_O = 1;
        pthread_create(&threads[0], NULL, oxygen, &thread_data[0]);

        thread_data[1].tid = 1;
        thread_data[1].waiting_H = 1;
        pthread_create(&threads[1], NULL, hydrogen, &thread_data[1]);

        thread_data[2].tid = 2;
        thread_data[2].waiting_H = 1;
        pthread_create(&threads[2], NULL, hydrogen, &thread_data[2]);

        pthread_join(threads[0], NULL);
        pthread_join(threads[1], NULL);
        pthread_join(threads[2], NULL);
    } else {
        for (int i = 0; i < NUM_THREADS; i++) {

            void *thread_func;//the function to call

            thread_data[i].tid = i;//set thread id to current i value

            if (rand()%2 == 0) {//if random amount < 0
                thread_func = hydrogen;//make Oxygen
            } else {//else amount > 0
                thread_func = oxygen;//make hydrogen
            }
            if ((errorCheck = pthread_create(&threads[i], NULL, thread_func, &thread_data[i]))) {
                fprintf(stderr, "error: pthread_create, %d\n", errorCheck);
                return EXIT_FAILURE;
            }
        }


        sleep(1);

        for (int i = 0; i < NUM_THREADS; ++i) {
            if ((errorCheck = pthread_join(threads[i], NULL))) {
                fprintf(stderr, "error: pthread_join, %d\n", errorCheck);
            }
        }
/*
        if ((errorCheck = pthread_join(finalThread, NULL))) {
            fprintf(stderr, "error: pthread_join, %d\n", errorCheck);
        }
        */
    }
    printf("All molecules crossed barrier...CLEANING UP!\n");
    return EXIT_SUCCESS;
}

int getRand() {
    return ((rand() % RAND_RANGE) - RAND_RANGE/2);
}

void *oxygen(void *arg) {
    thread_data_t *data = (thread_data_t *)arg;
    semwait(&mutex);
    //waiting_O = waiting_O + data->amount;
    fflush(stdout);
    printf("Thread: %d oxygen proccess made\twaiting hydrogen: %d waiting oxygen: %d \n ", data->tid, data->waiting_H, data->waiting_O);
        if (data->waiting_H >= 2) {
            for(int i = 0; i<2; i++){
                semsignal(&b);
                printf("Thread %d oxygen released\n", data->tid); //if 2 hydrogen, release oxygen
                fflush(stdout);
            }
            data->waiting_H -=2;//decrease hydrogen count by 2
            semsignal(&mutex);
        } 
        else {
            data->waiting_O += 1;//if no 2 hydrogen, increase oxygen count by 1
            semsignal(&mutex);
            semwait(&a);
            printf("Thread %d oxygen Waits\n", data->tid);
        }
    printf("Thread %d oxygen complete \n", data->tid);
    pthread_exit(NULL);
}

void *hydrogen(void *arg) {
    thread_data_t *data = (thread_data_t *)arg;
    semwait(&mutex);
    fflush(stdout);
    printf("Thread %d hydrogen process made, waiting hydrogen: %d waiting oxygen: %d \n", data->tid, data->waiting_H, data->waiting_O); 
    if (data->waiting_H >= 1 && data->waiting_O >=1) { //if hydrogen 1 and oxygen 1, then can make h20
        for(int i =0; i<2 ;i++){
            semsignal(&b); //signals hydrogen
            printf("Thread %d Hydrogen Released\n", data->tid);
            fflush(stdout);
        }

        data->waiting_H -= 1;
        semsignal(&a);
        data->waiting_O -= 1;
        semsignal(&mutex);
    }
    else {
        data->waiting_H += 1;
        semsignal(&mutex);
        semwait(&b);
        printf("Thread %d Hydrogen Waits \n", data->tid);

    } 
    pthread_exit(NULL);
}

/*
*   Error-checked semaphore wait.
*/
void semwait(sem_t *sem) {
    if (sem_wait(sem) < 0) {
        perror("sem_wait");
        exit(EXIT_FAILURE);
    }
}

/*
*   Error-checked semaphore signal.
*/
void semsignal(sem_t *sem) {
    if (sem_post(sem) < 0) {
        perror("sem_post");
        exit(EXIT_FAILURE);
    }
}

Solution

  • the -o flag is for the output executable, not the output after the executable runs. The garbage you're seeing is the result of your text editor/cat attempting to interpret the compiled code as printable characters :)

    Try this;

    all: main.c h2o.h
        gcc -Wall -pthread -std=c99 -o main main.c
        chmod 755 main
    clean:
        -rm main
    

    Then, in your Putty terminal;

    > make all
    > ./main > main.txt
    

    Then your program's output should be in main.txt.