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);
}
}
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.