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
$ ./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.
Related
i am trying to get continuous keyboard input in c and have tried following the answer found here. however, i am getting undefined reference errors when using ncurses functions.
my code:
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <ncurses.h>
typedef struct
{
int fps;
int width;
int height;
int frame;
} window;
typedef struct
{
int x;
int y;
} position;
typedef struct
{
position pos;
} snake;
int kbhit(void)
{
int ch = getch();
if (ch != ERR)
{
ungetch(ch);
return 1;
}
else
{
return 0;
}
}
void draw(window win, snake s)
{
for (int i = -1; i <= win.height; i++)
{
for (int j = -1; j <= win.width; j++)
{
if ((i == -1 || i == win.height) || (j == -1 || j == win.width))
{
printf("#");
}
else if (j == s.pos.x && i == s.pos.y)
{
printf("O");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
int main()
{
printf("Welcome to the Snake Game\n");
sleep(3);
window win = {1, 20, 10, 0};
snake s = {{19, 9}};
int key_code;
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
scrollok(stdscr, TRUE);
while (true)
{
printf("\e[1;1H\e[2J");
printf("%d\n", win.frame);
draw(win, s);
if (kbhit())
{
key_code = getch();
printf("%d", key_code);
}
usleep((int)((1.0 / win.fps) * 1000) * 1000);
win.frame++;
}
return 0;
}
output:
/usr/bin/ld: /tmp/ccZ2eIK1.o: in function `kbhit':
game.c:(.text+0xf): undefined reference to `stdscr'
/usr/bin/ld: game.c:(.text+0x17): undefined reference to `wgetch'
/usr/bin/ld: game.c:(.text+0x2a): undefined reference to `ungetch'
/usr/bin/ld: /tmp/ccZ2eIK1.o: in function `main':
game.c:(.text+0x136): undefined reference to `initscr'
/usr/bin/ld: game.c:(.text+0x13b): undefined reference to `cbreak'
/usr/bin/ld: game.c:(.text+0x140): undefined reference to `noecho'
/usr/bin/ld: game.c:(.text+0x147): undefined reference to `stdscr'
/usr/bin/ld: game.c:(.text+0x154): undefined reference to `nodelay'
/usr/bin/ld: game.c:(.text+0x15b): undefined reference to `stdscr'
/usr/bin/ld: game.c:(.text+0x168): undefined reference to `scrollok'
/usr/bin/ld: game.c:(.text+0x1b6): undefined reference to `stdscr'
/usr/bin/ld: game.c:(.text+0x1be): undefined reference to `wgetch'
collect2: error: ld returned 1 exit status
You must include the NCURSES library with the link. A portable way to do this is like this:
$ gcc -o game game.c $( pkg-config --cflags --libs mcurses )
Or just include the "-lncurses" library as mentioned previously.
On an RPM-based system, you'll need the ncurses-devel package installed on the build machine.
I am a starter to work with shared memory and I have implemented a parallel adder in which each of the k processors is implemented as a child process. Specifically, given a set of n integers and value of k, the main program creates k child processes, assigns each child process to compute the total of its assigned ceiling of n/k numbers, waits for the sub-total from each of the k child processes, sum up the sub-totals, and print the result of each sub-total as well as the overall total. I have not use threads.
This program is created for assignment in the college and they it is expected to run in any department computer.
This code correctly compile on Kali Linux but I can not compile and run on other Linux versions.
When I tried to compile on Ubuntu it gives the error saying
undefined reference to 'sem_init'
I used -lrt in the line of compiling. Please help me with this problem.
This is the code that I created.
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<errno.h>
#include<semaphore.h>
#include<unistd.h>
#include<math.h>
#include<stdlib.h>
#define BUFFER_SIZE 100
#define BUFFER_SUB 2
typedef struct
{
int bufMax;
int datalimit;
int buff[BUFFER_SIZE];
sem_t mutex, empty, full;
} shared_inputs;
typedef struct
{
int sub[BUFFER_SUB];
sem_t mutex,empty,full;
}sub_tot;
int main(int argc, char *argv[])
{
int x = 0;
int data,count,i,j,tot;
int n;
int k =atoi(argv[2]);
int assign_size;
count = tot =0;
int segment_id;
size_t segment_size = sizeof(shared_inputs);
segment_id = shmget(IPC_PRIVATE,segment_size,IPC_CREAT|0666);
shared_inputs *shared_memory = shmat(segment_id,NULL,0);
sem_init(&shared_memory->mutex,1,1);
sem_init(&shared_memory->empty,1,BUFFER_SIZE);
sem_init(&shared_memory->full,1,0);
int segment_idSubs;
size_t segment_size1 = sizeof(sub_tot);
segment_idSubs = shmget(IPC_PRIVATE,segment_size1,IPC_CREAT|0666);
sub_tot *subtotal = shmat(segment_idSubs,NULL,0);
sem_init(&subtotal->mutex,1,1);
sem_init(&subtotal->empty,1,BUFFER_SUB);
sem_init(&subtotal->full,1,0);
FILE *numFile;
numFile = fopen(argv[1], "r");
while(!feof(numFile))
{
fscanf(numFile,"%d",&data);
sem_wait(&shared_memory->empty);
sem_wait(&shared_memory->mutex);
shared_memory->buff[x] = data;
sem_post(&shared_memory->mutex);
sem_post(&shared_memory->full);
printf("%d ", shared_memory->buff[x]);
x++;
n = x;
}
assign_size = ceil((double)n/(double)k);
printf("\n");
shared_memory->datalimit = 0;
shared_memory->bufMax = n-1;
printf("assigned size : %d \n", assign_size);
printf("n : %d , k : %d \n",n,k);
for(i =0; i < k; i++)
{
int id;
int subt = 0;
id = fork();
if(id < 0) // error in fork
{
perror("Error in fork ");
exit(300);
}
else if(id == 0)//the new child process
{
for(j=0;j< assign_size; j++)//getting items from the shared memory
{
sem_wait(&shared_memory->full);
sem_wait(&shared_memory->mutex);
int num = shared_memory->buff[shared_memory->datalimit];
//printf("%d \n",shared_memory->buff[shared_memory->datalimit]);
shared_memory->datalimit++;
sem_post(&shared_memory->mutex);
sem_post(&shared_memory->empty);
subt = subt + num;
if(shared_memory->datalimit == shared_memory->bufMax)
{
break;
}
}
int pid = getpid();
sem_wait(&subtotal->empty);
sem_wait(&subtotal->mutex);
subtotal->sub[0] = pid;
subtotal->sub[1] = subt;
sem_post(&subtotal->mutex);
sem_post(&subtotal->full);
printf("Sub-total produced by Processor with ID %d: %d \n",pid,subt);
exit(0);
}
else//parent process
{
int status;
wait(&status);
sem_wait(&subtotal->full);
sem_wait(&subtotal->mutex);
int sub = subtotal->sub[1];
sem_post(&subtotal->mutex);
sem_post(&subtotal->empty);
tot = tot+sub;
}
}
printf("Total: %d \n",tot);
return 0;
}
Need to add -lpthread when compiling and use -lm and -lrt also.
You need to add #include <pthread.h> in order to make it work
Processor.c
#include<time.h>
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include<unistd.h>
#include"Process_struct.h"
sem_t empty;//semaphores
#define MAX_PROCS 5
#define EXIT 1
#define TRUE 1
char outbaseStr [100];
int numProcessors;
FILE *outLog=NULL;
FILE *file=NULL;
FILE *outFile=NULL;
FILE *temp=NULL;
pthread_t producer;//Producer Thread ID
pthread_t consumer[MAX_PROCS];//consumer thread ID
int main(int argc, char *argv[])
{
/* Initialize Data */
initializeData();
printf("argc equals %d\n", argc);
int num_processors=atoi(argv[2]);
int case_num=atoi(argv[3]);
char filename;
char *outfilename=argv[1];
printf("outfilename equals %s\n", outfilename);
printf("num_processors equals %d\n\n", num_processors);
switch(case_num)
{
case 1:
//printf("case 1\n");
/* Reading in from the text */
file = fopen("temp.txt", "wr");
/* fopen returns 0, the NULL pointer, on failure */
if(file==0||file==NULL)
{
printf("Error: couldn't open the file\n");
exit(EXIT);
}
/*****************************************************************************/
//write to temp
int length=argc-4;
for(int i=0;i<length;i++)
{
if(i%2==0)
{
//printf("%d ", atoi(argv[i+3]));
fprintf(file, "%d ", atoi(argv[i+4]));
}
else
{
//printf("%d\n", atoi(argv[i+3]));
fprintf(file,"%d\n", atoi(argv[i+4]));
}
}
/*****************************************************************************/
fclose(file);
file = fopen("temp.txt", "r");
/* Create the producer thread */
pthread_create(&producer, NULL, get_request, (void *)file);
break;
case 2:
//char filename[100];
//filename=argv[3];
//printf("usage: %s filename\n", argv[3]);
/* Reading in from the text */
file = fopen(argv[4], "r");
/* fopen returns 0, the NULL pointer, on failure */
if(file==0||file==NULL)
{
printf("Error: couldn't open the file\n");
exit(EXIT);
}
/* Create the producer thread */
pthread_create(&producer, NULL, get_request, (void *)file);
break;
default:
printf("Error: should be either case 1 or case 2\n");
exit(EXIT);
break;
}
pthread_join(producer, NULL);
//displayQ();
// Create the consumer threads
for(int i=0;i<num_processors;i++)
{
sprintf(outbaseStr, "%s.%ld", outfilename, (long)(i+1));
//printf("outbaseStr equals %s\n", outbaseStr);
outLog=fopen(outbaseStr, "w");
if(outLog==NULL)
{
printf("Error: couldn't open the file\n");
exit(EXIT);
}
pthread_create(&consumer[i], NULL, processor, (void *)outLog);
}
for(int i=0;i<num_processors;i++)
{
pthread_join(consumer[i], NULL);
}
//printf("\nfclose\n");
close((FILE *)file);
//fclose((FILE *)file);
if(case_num==1)
{
if(remove("temp.txt")!=0)
{
printf("error deleting file");
}
else
{
//printf("success deleting file");
}
}
}
Process_struct.c
#include<time.h>
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include<unistd.h>
#include"Process_struct.h"
sem_t empty;//semaphores
#define MAX_PROCS 5
#define EXIT 1
#define TRUE 1
char outbaseStr [100];
int numProcessors;
FILE *outLog=NULL;
FILE *file=NULL;
FILE *outFile=NULL;
FILE *temp=NULL;
pthread_t producer;//Producer Thread ID
pthread_t consumer[MAX_PROCS];//consumer thread ID
void initializeData()
{
//printf("initializeData\n");
//Create the empty semaphore and initialize it
sem_init(&empty, 0, MAX_PROCS);
// pthread_attr_init(attr);
}
void *get_request(void *argv)//this produces a queue
{
prcmd_t *process;
//printf("get_request\n");
if(file==NULL)
{
printf("\nwe have a file null error\n");
}
while(!feof(file))
{
process=(prcmd_t *)malloc(sizeof(prcmd_t));
fscanf(file, "%d %d", &process->owner, &process->burst_time);
if(process->owner!=0||process->burst_time!=0)
{
//printf("%d %d\n", process->owner, process->burst_time);
if(add_queue(process)==-1)
{
printf("failure from add_queue");
}
}
}
//printf("this is the end of get_request\n");
}
void *processor(void *argv)//this consumes a queue
{
prcmd_t *process;
// process=(prcmd_t *)malloc(sizeof(prcmd_t));
process=pr_head;
int sleep_time=process->burst_time;
//printf("\nprocessor\n");
while(TRUE)
{
if(get_number_request()>0)
{
if(remove_queue(&process)==0)
{
fprintf(outLog, "\n->Process with id %d and it %d de-equeue by thread \n", process->owner, process->burst_time);
clock_t start=clock();
sleep(process->burst_time);
clock_t end=clock();
fprintf(outLog, "\nSlept for %d seconds\n", sleep_time);
}
}
close((FILE *)outLog);
//fclose((FILE *)outLog);
//printf("the end of the processor\n");
//displayQ();
return NULL;
}
}
int get_number_request()
{
return pending_request;
}
void displayQ()
{
printf("\n\nthis is the beginning of displayQ\n");
prcmd_t *process=pr_head;
do
{
printf("%d %d\n", process->owner, process->burst_time);
process=process->next;
}while(process!=NULL);
printf("\nthe end of displayQ\n\n");
}
int add_queue(prcmd_t *node)
{
prcmd_t *temp;
temp=node;
pthread_mutex_lock(&prmutex);
//printf("add_queue\n");
//printf("%d %d\n", temp->owner, temp->burst_time);
/* adding a linkedlist to a queue */
if(pr_head==NULL)//then pr_tail==NULL
{
//printf("pr_head==NULL\n");
temp->next=NULL;
pr_head=temp;
pr_tail=temp;
}
else
{
//printf("pr_head!=NULL\n");
temp->next=NULL;
pr_tail->next=temp;
pr_tail=temp;
}
pending_request++;
pthread_mutex_unlock(&prmutex);
//printf("add_queue success\n");
return(0);
}
int remove_queue(prcmd_t **node)
{
//printf("\nremove_queue/enqueue\n");
pthread_mutex_lock(&prmutex);
prcmd_t *temp;
// printf("this is the end of remove_queue/enqueue and is returning 0\n");
if(pr_head==NULL)
{
//printf("pr_head==NULL");
pr_head = pr_tail = NULL; // Reset everything to empty queue
pthread_mutex_unlock(&prmutex);
//printf("this is the end of remove_queue/enqueue and is returning -1\n");
return(-1);
}
else
{
//printf("pr_head!=NULL\n");
temp=pr_head;
temp->next=pr_head->next;
pr_head=temp->next;
pending_request--;
pthread_mutex_unlock(&prmutex);
//printf("this is the end of remove_queue/enqueue and is returning 0\n");
return(0);
}
}
Process_struct.h
GNU nano 2.2.6 File: Process_struct.h
#include<time.h>
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include<unistd.h>
typedef struct pr_struct
{
int owner;
int burst_time;
struct pr_struct *next;
} prcmd_t;
void displayQ();//this displays the queue
void initializeData();//initializes the data for the program
void *get_request(void *args);//to be calls as a thread to enqueue input reques$
void *processor(void *args);//which removes a request from the process request $
int get_number_request();//returns the number of request
int add_queue(prcmd_t *);//adds a node at the end of the request queue
int remove_queue(prcmd_t **);//removes a node for the queue
#define MAX_PROCS 5
#define EXIT 1
#define TRUE 1
This is the error I have:
/tmp/ccvDJUQI.o:(.bss+0x0): multiple definition of `outLog'
/tmp/cc4RWdZ4.o:(.bss+0x0): first defined here
/tmp/ccvDJUQI.o:(.bss+0x8): multiple definition of `file'
/tmp/cc4RWdZ4.o:(.bss+0x8): first defined here
/tmp/ccvDJUQI.o:(.bss+0x10): multiple definition of `outFile'
/tmp/cc4RWdZ4.o:(.bss+0x10): first defined here
/tmp/ccvDJUQI.o:(.bss+0x18): multiple definition of `temp'
/tmp/cc4RWdZ4.o:(.bss+0x18): first defined here
collect2: error: ld returned 1 exit status
make: *** [Multiprocessor] Error 1
Whenever I go to run my make file this is the error I get. I don't understand where the error would be so I can't find it and change it. I was hoping someone could tell me what collect2: error: ld returned 1 exit status means and where the error would be at.
From your comment, it looks like you're trying to compile header files
gcc Processor.c Process_struct.h Process_struct.c -o Multiprocessor -std=c99 -lm -lpthread
A header file is included in a .c file and not compiled separately. Your command line should more look like
gcc Processor.c Process_struct.c -o Multiprocessor -std=c99 -lm -lpthread
Another source of this kind of errors, is when you define variables in a header file and include the header file in multiple source files, e.g. in Process_struct.h
FILE *file = NULL;
char temp[] = "/tmp";
When you include this header file in Processor.c and Process_struct.c, you define these variables in both sources and as a consequence get multiple defined variables.
To fix this, you must not define, but only declare the variables in the header file. You can then define them in one source file, e.g.
Process_struct.h:
extern FILE *file;
extern char temp[];
and in Process_struct.c:
FILE *file = NULL;
char temp[] = "/tmp";
Yet another source of multiple definitions is just that, you have defined the same variable in multiple places. This means when you have
Processor.c:
FILE *file = NULL;
char temp[] = "/tmp";
Process_struct.c:
FILE *file = NULL;
char temp[] = "/tmp";
you will get this error. The fix for this depends on your intention. If these variables are local to the file (independent from each other) narrow their scope to the file by prefixing with static
static FILE *file = NULL;
static char temp[] = "/tmp";
However, if you want to share the variables between these two sources, you must keep one definition and make the other one a declaration only. Better yet, move the declaration to a header file and keep the definition in only one source file, as in the second part above.
In any case, you should structure your makefile a bit differently. Use the built-in rules as much as possible, see Using Implicit Rules. E.g.
CFLAGS = -std=c99 -pthread
LDLIBS = -lm -lpthread
OBJS = Processor.o Process_struct.o
Multiprocessor: $(OBJS)
$(CC) $(CFLAGS) -o $# $(OBJS) $(LDLIBS)
For all user looking for an answer to collect2: error: ld returned 1 exit status, remember that it is helpful to make all the variables in your header file a STATIC variable. That's what made my error go away so to all other users that could be the answer to your error.
I wanted to compare AES algorithm performance from libtomcrypt in Windows and Ubuntu by creating a benchmark-like file, but I have got errors while coding it. Please help me. Below is my file for comparing:
Compare.c:
`#include <time.h> `
#include <tomcrypt.h>
#define MIN_TIME 10.0
#define MIN_ITERS 20 `
double test_rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) {
int iterations = 0;
clock_t start;
double elapsed=0.0;
int out;
start=clock();
do{
out = rijndael_ecb_encrypt(pt, ct, skey);
iterations++;
elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
} while(elapsed<MIN_TIME || iterations<MIN_ITERS);
elapsed=1000.0*elapsed/iterations;
printf("%s \n",pt);
printf("%s \n",skey->data);
printf("%s \n",ct);
printf("iterations: %8d \n",iterations);
printf("%8.2lf ms per iteration \n",elapsed);
printf("out: %d \n",out);
return elapsed;
}
int main() {
unsigned char pt[22]="-K4)<i50~'APg2fa7DiV";
unsigned char ct[22];
unsigned char key[16]="EDB1C6D13FC72";
symmetric_key *skey;
int err;
double tout1;
printf("%x",sizeof(pt));
printf("%l",sizeof(key));
if((err=rijndael_setup(key,16,0,skey))!=CRYPT_OK) {
printf("%s",error_to_string(err));
return -1;
}
tout1=test_rijndael_ecb_encrypt(pt,ct,skey);
printf("%s \n",ct);
printf("%f",tout1);
return 0;
}
But when I compile this it shows runtime errors as:
gcc -o "TestC" ./src/TestC.o
./src/TestC.o: In function `test_rijndael_ecb_encrypt':
/home/anvesh/workspace/TestC/Debug/../src/TestC.c:27: undefined reference to `rijndael_ecb_encrypt'
./src/TestC.o: In function `test_rijndael_ecb_decrypt':
/home/anvesh/workspace/TestC/Debug/../src/TestC.c:53: undefined reference to `rijndael_ecb_decrypt'
./src/TestC.o: In function `main':
/home/anvesh/workspace/TestC/Debug/../src/TestC.c:82: undefined reference to `rijndael_setup'
/home/anvesh/workspace/TestC/Debug/../src/TestC.c:83: undefined reference to `error_to_string'
collect2: error: ld returned 1 exit status
make: *** [TestC] Error 1
Where did I go wrong?
You forgot to link with tomcrypt library. Compile with -ltomcrypt to link the library:
gcc file.c -ltomcrypt
I am new to multithreading, and any answers will be greatly appreciated. I am running an example from a tutorial which uses 3 threads; two created by the user, and one for main itself. Here's the code:
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#define NUM_EMPLOYEES 2
/* global mutex for our program. assignment initializes it */
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
struct employee {
int number;
int id;
char first_name[20];
char last_name[30];
char department[30];
int room_number;
};
/* global variable - our employees array, with 2 employees */
struct employee employees[] = {
{1, 12345678, "danny", "cohen", "Accounting", 101},
{2, 87654321, "moshe", "levy", "Programmers", 202}
};
/* global variable - employee of the day */
struct employee employee_of_the_day;
void copy_employee(struct employee *from, struct employee *to) {
int rc; /* contain mutex lock/unlock results */
/*lock the mutex, to assure exclusive access to 'a' and 'b' */
rc = pthread_mutex_lock(&a_mutex);
to->number = from->number;
to->id = from->id;
strcpy(to->first_name, from->first_name);
strcpy(to->last_name, from->last_name);
strcpy(to->department, from->department);
to->room_number = from->room_number;
/* unlock mutex */
rc = pthread_mutex_unlock(&a_mutex);
}
/* function to be executed by the variable setting threads thread */
void *do_loop(void *data) {
int my_num = *((int*)data);
while(1) {
/* set employee of the day to be the one with number 'my_num' */
copy_employee(&employees[my_num-1], &employee_of_the_day);
}
}
/* program's execution begins in main */
int main(int argc, char *argv[]) {
int i;
int thr_id1;
int thr_id2;
pthread_t p_thread1;
pthread_t p_thread2;
int num1 = 1;
int num2 = 2;
struct employee eotd;
struct employee *worker;
/* initialize employee of the day to first 1 */
copy_employee(&employees[0], &employee_of_the_day);
/* create a new thread that will execute 'do_loop()' with '1' */
thr_id1 = pthread_create(&p_thread1, NULL, do_loop, (void*)&num1);
/* create a new thread that will execute 'do_loop()' with '2' */
thr_id2 = pthread_create(&p_thread2, NULL, do_loop, (void*)&num2);
/* run a loop that verifies integrity of 'employee of the day' many */
/* many times.... */
for (i = 0; i < 600000; i++) {
/* save contents of 'employee of the day' to local 'worker' */
copy_employee(&employee_of_the_day, &eotd);
worker = &employees[eotd.number-1];
/* compare employees */
if (eotd.id != worker->id) {
printf("mismatching 'id', %d != %d (loop '%d')\n",
eotd.id, worker->id, i);
exit(0);
}
if (strcmp(eotd.first_name, worker->first_name) != 0) {
printf("mismatching 'first_name' , %s != %s (loop '%d')\n",
eotd.first_name, worker->first_name, i);
exit(0);
}
if (strcmp(eotd.last_name, worker->last_name) != 0) {
printf("mismatching 'last_name' , %s != %s (loop '%d')\n",
eotd.last_name, worker->last_name, i);
exit(0);
}
if (strcmp(eotd.department, worker->department) != 0) {
printf("mismatching 'department' , %s != %s (loop '%d')\n",
eotd.department, worker->department, i);
exit(0);
}
if (eotd.room_number != worker->room_number) {
printf("mismatching 'room_number' , %d != %d (loop '%d')\n",
eotd.room_number, worker->room_number, i);
exit(0);
}
}
printf("Glory, employees contents was always consistent\n");
return 0;
}
I basically want to confirm that in the for loop in main, the following statement
copy_employee(&employee_of_the_day, &eotd);
could be executed by ANY of the 3 threads; am I right?
The fact that the subsequent comparisons are obviously not atomic raises some confusions. Any clarifications/corrections to this will be greatly helpful.
Incidentally, any good recommendations for tutorials on multithreading in C?
Thanks a lot!
No, the code in main is executed by only one thread.
The atomicity is ensured in copy_employee functions using mutexes.
Your main thread (and none of the worker threads) will execute everything within main() and then end. Both of your worker threads will execute everything within do_loop() and end once they leave the function.
This sounds a bit like you're confusing phtread_create() with fork(). pthread_create() will use the function provided as the entry point while fork() will start from the position it's been called.
I basically want to confirm that in the for loop in main, the following statement
copy_employee(&employee_of_the_day, &eotd);
could be executed by ANY of the 3 threads; am I right?
Not really, since that statement is only executed by the main thread and not by the other two threads.