-1

I have a C program. I want to run it on Linux. But, when I am entering gcc seekingtutor.c -o seek I am getting error. And, sometimes its showing file not exists on the directory. Is there any way I can run this program?

Code is here in GitHub

I want to run the following code on linux terminal. I am seeking for the command it needs to run. I think pthread compiling is needed.

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

//maximum student numbers
#define Max_stu_size 2000
//const int Max_stu_size=2000;

//check how many students have done.
//then coordinate and tutors threads can terminate
int done=0;
int totalRequests=0;
int totalSessions=0;
int tutoringNow=0;

void *student_thread(void *student_id);
void *tutor_thread(void *tutor_id);
void *coordinator_thread();
//void *coordinator_thread(void *);

int student_num=0;
int tutor_num=0;
int help_num=0;
int chair_num=0;
int occupied_chair_num=0;

int newArrivedStudentQueue[Max_stu_size];
int tutorFinishedQueue[Max_stu_size];
int priorityQueue[Max_stu_size][2];
int student_priority[Max_stu_size];
int student_ids[Max_stu_size];
int tutor_ids[Max_stu_size];

sem_t sem_student;
sem_t sem_coordinator;
//sem_t sem_tutorToStudent[Max_stu_size];
pthread_mutex_t seatLock;
pthread_mutex_t queueLock;
pthread_mutex_t tutorFinishedQueueLock;

int main(int argc, const char * argv[]) {

    //test
    /*student_num=10;
    tutor_num=3;
    chair_num=4;
    help_num=5;*/
    
    
    //get input argument
    if (argc != 5){
        printf("Usage: <# of Students> <# of tutors> <# of chairs> <# of help>\n");
        exit(-1);
    }
    
    student_num=atoi(argv[1]);
    tutor_num=atoi(argv[2]);
    chair_num=atoi(argv[3]);
    help_num=atoi(argv[4]);
    
    if(student_num > Max_stu_size || tutor_num > Max_stu_size){
        printf("Max student number is: %d; Max tutor number is: %d\n", Max_stu_size, Max_stu_size);
        exit(-1);
    }
    
    //init arrays
    int i;
    for(i=0;i<student_num;i++){
        newArrivedStudentQueue[i]=-1;
        tutorFinishedQueue[i]=-1;
        priorityQueue[i][0]=-1;
        priorityQueue[i][1]=-1;
        student_priority[i]=0;
    }
    
    //init lock and semaphore
    sem_init(&sem_student,0,0);
    sem_init(&sem_coordinator,0,0);
    pthread_mutex_init(&seatLock,NULL);
    pthread_mutex_init(&queueLock,NULL);
    pthread_mutex_init(&tutorFinishedQueueLock,NULL);
    /*for(i=0;i<student_num;i++){
        sem_init(&sem_tutorToStudent[i],0,0);
    }*/
    
    //allocate threads
    pthread_t students[student_num];
    pthread_t tutors[tutor_num];
    pthread_t coordinator;
    
    //create threads
    assert(pthread_create(&coordinator,NULL,coordinator_thread,NULL)==0);
    
    for(i = 0; i < student_num; i++)
    {
        student_ids[i] = i + 1;
        assert(pthread_create(&students[i], NULL, student_thread, (void*) &student_ids[i])==0);
    }
    
    for(i = 0; i < tutor_num; i++)
    {
        tutor_ids[i] = i + student_num + 1;
        assert(pthread_create(&tutors[i], NULL, tutor_thread, (void*) &tutor_ids[i])==0);
    }
    
    //join threads
    pthread_join(coordinator, NULL);
    
    for(i =0; i < student_num; i++)
    {
        pthread_join(students[i],NULL);
    }
    
    for(i =0; i < tutor_num; i++)
    {
        pthread_join(tutors[i],NULL);
    }
    
    return 0;
}

//students action.
//1.program;
//2.find the empty seat and nofity coordinator;
//3.wait tutor to wake it up and finish tutoring.
void *student_thread(void *student_id){
    int id_student=*(int*)student_id;
    
    while(1){
        if(student_priority[id_student-1]>=help_num) {
            
            pthread_mutex_lock(&seatLock);
            done++;
            pthread_mutex_unlock(&seatLock);

            //notify coordinate to terminate
            sem_post(&sem_student);
            
            //printf("------student %d terminate------\n",id_student);
            pthread_exit(NULL);
        }
        
        //programing
        //sleeping for a random amount of time up to 2 ms
        float programTime=(float)(rand()%200)/100;
        //printf("sleep time = %f.\n", programTime);
        usleep(programTime);
        
        pthread_mutex_lock(&seatLock);
        if(occupied_chair_num>=chair_num){
            //St: Student x found no empty chair. Will try again later
            printf("St: Student %d found no empty chair. Will try again later.\n",id_student);
            pthread_mutex_unlock(&seatLock);
            continue;
        }
        
        occupied_chair_num++;
        totalRequests++;
        newArrivedStudentQueue[id_student-1]=totalRequests;
        
        //St: Student x takes a seat. Empty chairs = <# of empty chairs>.
        printf("St: Student %d takes a seat. Empty chairs = %d\n",id_student,chair_num-occupied_chair_num);
        pthread_mutex_unlock(&seatLock);
        
        //notify coordinator that student seated.
        sem_post(&sem_student);
        
        //wait to be tutored.
        while(tutorFinishedQueue[id_student-1]==-1);
        //sem_wait(&sem_tutorToStudent[id_student-1]);

        //St: Student x received help from Tutor y.
        printf("St: Student %d received help from Tutor %d.\n",id_student,tutorFinishedQueue[id_student-1]-student_num);
        
        //reset the shared data
        pthread_mutex_lock(&tutorFinishedQueueLock);
        tutorFinishedQueue[id_student-1]=-1;
        pthread_mutex_unlock(&tutorFinishedQueueLock);
        
        //tutored times++ after tutoring.
        pthread_mutex_lock(&seatLock);
        student_priority[id_student-1]++;
        pthread_mutex_unlock(&seatLock);
    }
}

//tutors action
//1.wait coordinator's nofitication;
//2.find student from queue with highest priority;
//3.tutoring and notify student it's done;
void *tutor_thread(void *tutor_id){
    int id_tutor=*(int*)tutor_id;
    int studentTutoredTimes;
    //students with same tutored times, who come first has higher priority
    int studentSequence;
    int id_student;
    
    while(1){
        //if all students finish, tutors threads terminate.
        if(done==student_num){
            //printf("------tutor %d terminate------\n",id_tutor);
            pthread_exit(NULL);
        }
        
        studentTutoredTimes=help_num-1;
        studentSequence=student_num*help_num+1;
        id_student=-1;
        
        //wait coordinator's notification
        sem_wait(&sem_coordinator);
        
        pthread_mutex_lock(&seatLock);
        //find student with highest priority from priority queue;
        //if students with same tutored times, who come first has higher priority
        int i;
        for(i=0;i<student_num;i++){
            if(priorityQueue[i][0]>-1 && priorityQueue[i][0]<=studentTutoredTimes
               && priorityQueue[i][1]<studentSequence){
                studentTutoredTimes=priorityQueue[i][0];
                studentSequence=priorityQueue[i][1];
                id_student=student_ids[i];
            }
        }
        
        //in case no student in the queue.
        if(id_student==-1) {
            pthread_mutex_unlock(&seatLock);
            continue;
        }
        
        //pop the student(reset the priority queue)
        priorityQueue[id_student-1][0]=-1;
        priorityQueue[id_student-1][1]=-1;
        
        //occupied chair--
        occupied_chair_num--;
        //all the students who are receiving tutoring now, since each tutor time slice is very tiny, so it's common that the tutoringNow is 0.
        tutoringNow++;
        pthread_mutex_unlock(&seatLock);
        
        //tutoring
        // sleeping for a random amount of time up to 0.2 ms
        float tutorTime=(float)(rand()%200)/1000;
        usleep(tutorTime);
        
        //after tutoring
        pthread_mutex_lock(&seatLock);
        //need to do tutoringNow-- after tutoring.
        tutoringNow--;
        totalSessions++;
        printf("Tu: Student %d tutored by Tutor %d. Students tutored now = %d. Total sessions tutored = %d\n",id_student,id_tutor-student_num,tutoringNow,totalSessions);
        pthread_mutex_unlock(&seatLock);

        //update shared data so student can know who tutored him.
        pthread_mutex_lock(&tutorFinishedQueueLock);
        tutorFinishedQueue[id_student-1]=id_tutor;
        pthread_mutex_unlock(&tutorFinishedQueueLock);
        
        //wake up the tutored student.
        //sem_post(&sem_tutorToStudent[id_student-1]);
    }
}

//coordinator action.
//1.wait student's nofitication;
//2.push student into the queue with priority;
//3.notify tutor
void *coordinator_thread(){
    while(1){
        //if all students finish, tutors threads and coordinate thread terminate.
        if(done==student_num){
            //terminate tutors first
            int i;
            for(i=0;i<tutor_num;i++){
            //notify tutors to terminate
            sem_post(&sem_coordinator);
            }
            
            //terminate coordinate itself
            //printf("------coordinator terminate------\n");
            pthread_exit(NULL);
        }
        
        //wait student's notification
        sem_wait(&sem_student);
        
        pthread_mutex_lock(&seatLock);
        //find the students who just seated and push them into the priority queue
        int i;
        for(i=0;i<student_num;i++){
            if(newArrivedStudentQueue[i]>-1){
                priorityQueue[i][0]=student_priority[i];
                priorityQueue[i][1]=newArrivedStudentQueue[i];
                
                printf("Co: Student %d with priority %d in the queue. Waiting students now = %d. Total requests = %d\n",student_ids[i],student_priority[i],occupied_chair_num,totalRequests);
                newArrivedStudentQueue[i]=-1;
                
                //notify tutor that student is in the queue.
                sem_post(&sem_coordinator);
            }
        }
        pthread_mutex_unlock(&seatLock);
    }
}

Error:

gcc seekingtutor.c -o seek
/usr/bin/ld: /tmp/ccsL8SkI.o: in function `main':
seekingtutor.c:(.text+0x1a2): undefined reference to `sem_init'
/usr/bin/ld: seekingtutor.c:(.text+0x1b8): undefined reference to `sem_init'
/usr/bin/ld: seekingtutor.c:(.text+0x38e): undefined reference to `pthread_create'
/usr/bin/ld: seekingtutor.c:(.text+0x41c): undefined reference to `pthread_create'
/usr/bin/ld: seekingtutor.c:(.text+0x4c5): undefined reference to `pthread_create'
/usr/bin/ld: seekingtutor.c:(.text+0x50c): undefined reference to `pthread_join'
/usr/bin/ld: seekingtutor.c:(.text+0x530): undefined reference to `pthread_join'
/usr/bin/ld: seekingtutor.c:(.text+0x563): undefined reference to `pthread_join'
/usr/bin/ld: /tmp/ccsL8SkI.o: in function `student_thread':
seekingtutor.c:(.text+0x60d): undefined reference to `sem_post'
/usr/bin/ld: seekingtutor.c:(.text+0x722): undefined reference to `sem_post'
/usr/bin/ld: /tmp/ccsL8SkI.o: in function `tutor_thread':
seekingtutor.c:(.text+0x866): undefined reference to `sem_wait'
/usr/bin/ld: /tmp/ccsL8SkI.o: in function `coordinator_thread':
seekingtutor.c:(.text+0xad7): undefined reference to `sem_post'
/usr/bin/ld: seekingtutor.c:(.text+0xafc): undefined reference to `sem_wait'
/usr/bin/ld: seekingtutor.c:(.text+0xc08): undefined reference to `sem_post'
collect2: error: ld returned 1 exit status

  • Please include the exact error message in your question so that people don’t have to guess what it is. – Jeremy Friesner Jan 22 '22 at 06:22
  • `gcc seekingtutor.c -o seek -l pthread` – Yuri Ginsburg Jan 22 '22 at 06:28
  • 4
    Add `-pthread` to the compiler options – Shawn Jan 22 '22 at 06:29
  • yes done, its compiled. then how to run? –  Jan 22 '22 at 06:30
  • 2
    (and `-Wall -Wextra` to turn on a healthy set of warnings and `-g` to emit debugging information so your program can play nice with gdb or other debuggers) – Shawn Jan 22 '22 at 06:30
  • @Shawn can you write the whole process in answer pls. –  Jan 22 '22 at 06:32
  • `./seekingtutor bash: ./seekingtutor: No such file or directory` this error showing on run command, I am on the right directory. –  Jan 22 '22 at 06:37
  • 1
    `./seek` to run. – Yuri Ginsburg Jan 22 '22 at 06:45
  • 1
    You will need to add `-D_GNU_SOURCE` (or `-std=gnu11`) as a compile option for `usleep()`. Program also shows why multi-threaded programs are subject to deadlock. Try with `./seek 10 2 4 3` – David C. Rankin Jan 22 '22 at 06:58
  • Does this answer your question? [Undefined reference to pthread\_create in Linux](https://stackoverflow.com/questions/1662909/undefined-reference-to-pthread-create-in-linux) – yivi Jan 24 '22 at 16:46
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Jan 31 '22 at 21:31

1 Answers1

2
$ ./seekingtutor
bash: ./seekingtutor: No such file or directory

While executing, you need to run it using ./seek, not ./seekingtutor as -o seek outputs the executable with the name seek


The linker has shown errors collect2: error: ld returned 1 exit status, so it did not output the executable.

It seems like it needs pthread. So run gcc seekingtutor.c -o seek -lpthread to compile it, and try. It works for me here.

https://man7.org/linux/man-pages/man3/sem_init.3.html says

Link with -pthread.

Example person
  • 3,198
  • 3
  • 18
  • 45