The code below is a sample provided by the book in my Operating Systems course.
When compiling it I get the error shown below it.
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
int main(int argc, char *argv[])
{
int i, policy;
pthread_t tid[NUM_THREADS];
pthread_attr_t attr;
pthread_attr_init(&attr);
if(pthread_attr_getschedpolicy(&attr, &policy) != 0)
fprintf(stderr, "Unable to get policy.\n");
else{
if(policy == SCHED_OTHER)
printf("SCHED_OTHER\n");
else if(policy == SCHED_RR)
printf("SCHED_RR\n");
else if(policy == SCHED_FIFO)
printf("SCHED_FIFO\n");
}
if(pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0)
fprintf(stderr, "Unable to set policy.\n");
/* create the threads */
for(i = 0; i < NUM_THREADS; i++)
pthread_create(&tid[i], &attr, runner, NULL);
/* now join on each thread */
for(i = 0; i < NUM_THREADS; i++)
pthread_join(tid[i], NULL);
}
/* Each thread will begin control in this function */
void *runner(void *param)
{
/* do some work... */
pthread_exit(0);
}
I compiled it using this command...
gcc linux_scheduling.c -o scheduling
However, I get this error.
linux_scheduling.c:32:34: error: 'runner' undeclared (first use in this function)
pthread_create(&tid[i], &attr, runner, NULL);
^
linux_scheduling.c:32:34: note: each undeclared identifier is report only once for each function it appears in
I tried adding -pthread:
gcc linux_scheduling.c -o scheduling -pthread
but the error remains.
Thanks for your help!
You have the correct compiling command:
gcc linux_scheduling.c -o scheduling -pthread
but you need to put:
void *runner(void *param);
ahead of the start of main to declare it:
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *runner(void *param);
int main(int argc, char *argv[])
{
...
Declare prototype of runner or if you don't want to declare then define the function before main. This is because main is referring the function and gives you such errors
Related
I want to modify the multithread program on the Linux operating system using this Pthread API.
#include <pthread.h>
#include <stdio.h>
int sum;
void *runner(void *param);
int main(int argc, char *argv[]) {
pthread_t tid
pthread_attr_t attr;
if (argc != 2) {
fprintf(stderr, "usage: a.out <integer value>\n");
return -1;
}
if (atoi(argv[1]) < 0) {
fprintf(stderr, "%d must be >=0\n", atoi(argv[1]));
return -1;
}
pthread_attr_init(&attr);
pthread_create(&tid, &attr, runner, argv[1]);
pthread_join(tid, NULL);
printf("sum = %d\n", sum);
}
void *runner(void *param);
{
int i, upper = atoi(param);
sum = 0;
for (i = 1; i <= upper; i++)
sum += i;
pthread exit(0);
}
I want to change that program into a program that has 2 threads that work together to add a number. But i don't know how to change it, Thanks again for any help that can be offered. I am sorry,because I'm not good at explaining.
first there is 3 errors : the pthread tid declaration has no ";", then there is one at the end of your runner()* function declaration, and last but not least, a underscore is missing on the last line pthread_exit(0)
beware ahah
ok for vars :
pthread_t tid;
pthread_t tid2;
pthread_attr_t attr;
pthread_attr_t attr2;
and in the code after the ifs, add this :
pthread_attr_init(&attr);
pthread_attr_init(&attr2);
pthread_create(&tid, &attr, runner, argv[1]);
pthread_create(&tid2, &attr2, runner, argv[2]); // not sure for argv[2]?
not sure for argv[2], it depends if it's 2 different numbers?
pthread_join are no use, they are here only for pausing threads, i think that if you want them to work in parallel, you need to only do "pthread_create" and they should work in parallel (but was i saw on my CS class on parallel programming 3 years ago, it will never be "real real" parallel because only the OS can control this and you need to be some kind of a super root to be able to really control the threads
I mean
it won't be faster because it will not be real parallel prog
I'm not exactly sure what you want, but a really quick and dirty solution based on the existing code is below. I'm assuming you just want two thread to sum a single variable to the input.
An explanation of what's going on: I had to fix some minor syntax issues you have in your code, one big one being the semicolon at the end of the runner function definition. I added a mutex to define a critical section in the runner's for loop. It makes sure only 1 thread can update the sum. I'm assuming you want the sum to equal the input, so we just increment it by 1 and check before incrementing whether the value is still below. Like I said, it's quite quick and dirty, not really the ideal solution. To create two threads, we just call the thread create function twice in main.
See https://computing.llnl.gov/tutorials/pthreads/#Mutexes for more important about mutexes and the pthread library.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
int sum = 0; // set it once globally
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
void *runner(void *param);
int main(int argc, char *argv[]) {
pthread_t tid1, tid2;
pthread_attr_t attr;
if (argc != 2) {
fprintf(stderr, "usage: a.out <integer value>\n");
return -1;
}
if (atoi(argv[1]) < 0) {
fprintf(stderr, "%d must be >=0\n", atoi(argv[1]));
return -1;
}
pthread_attr_init(&attr);
pthread_create(&tid1, &attr, runner, argv[1]);
pthread_create(&tid2, &attr, runner, argv[1]);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("sum = %d\n", sum);
}
void *runner(void *param) {
int i, upper = atoi(param);
// sum = 0;
int t = pthread_self();
for (i = 1; i <= upper; i++) {
pthread_mutex_lock(&mtx);
if (sum < upper) {
printf("%d incrementing\n", t);
sum += 1;
}
pthread_mutex_unlock(&mtx);
}
pthread_exit(0);
}
Compile with cc -o main main.c -pthread.
This is for an assignment, but right now I'm just playing around with a code I found in a tutorial, but I can't seem to get it to compile, and I don't understand the error I receive. My code is below:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *myfunc (void *myvar);
int main( int argc, char *argv[])
{
pthread_t thread1;
pthread_t thread2;
char *msg1 = "First thread";
char *msg2 = "Second thread";
int ret1;
int ret2;
//create threads
ret1 = pthread_create(&thread1, NULL, myfunc, (void*) msg1);
ret2 = pthread_create(&thread2, NULL, myfunc, (void*) msg2);
printf("Main function after pthread_create\n");
//join threads back to main process once completed
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Return thread ret1 = %d\n", ret1);
printf("Return thread ret2 = %d\n", ret2);
return 0;
}
void *myfunc(void *myvar)
{
char *msg;
msg = (char *) myvar;
int i;
for (i = 0; i < 10; i++) {
printf("%s%d\n", msg, i);
sleep(1);
}
return NULL;
}
I compiled using gcc -o c_thread c_thread.c
and received the error:
/usr/lib/gcc/x86_64-linux-gnu/5/.../.../.../x84_64-linux-gnu/ctr1.o: In function '_start':
/build/buildd/glibc-2.21/csu/.../sysdeps/x86_64/start.S:114: undefined reference to 'main'
collect2: error: ld returned 1 exit status
I know other questions have been asked about similar errors, but every answer I found related to a code which used a 'nontraditional' main function, whereas mine follows the standard int main(int argc char *argv[]) format
Any suggestions would be greatly appreciated
Your missing the -lpthread when compiling
Try compiling as following via terminal or adjusting the settings from the linker if you're working in an IDE:
gcc pro.c -o pro -lpthread
Suppose pro.c was your program file.
i am using LINUX 10.04 i think this is not a problem,anyway i have a
Weird Error.
To me all looks perfect.
So what is the problem?
Sorry for this format type.i am new here.
//COMPILE with: gcc -g -Wall -pthread pthread_ex_book_pg193.c -lpthread -o MYthread
/* the program is simple.We create two threads One is for the main () and th esecond with the pthread_create().
The second thread calls a function runner() to calculate a sum and when it finishes it returns to the main thread */
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int sum;
void *runner(void *argv[]);
int main (int argc,char *argv[]){
pthread_t tid; //thread id
pthread_attr_t attr;//thread attributes
if (argc!=2){
fprintf(stderr,"usage: a.out<integer value> \n");
return -1;
}
if (atoi(argv[1]) < 0){
fprintf(stderr, "%d must be >=0\n ",atoi(argv[1]));
return -1;
}
pthread_attr_init(&attr);
pthread_create(&tid,&attr,runner,argv[1]);
pthread_join(tid,NULL);
printf("sum = %d \n",sum);
}
void *runner(void *param){
int i;
int upper = atoi(param);
sum=0;
for (i=1;i<=upper;i++){
sum=sum+i;
pthread_exit(0);
}
}
Change
void *runner(void *argv[]);
to
void *runner(void *argv);
(1) Your forward declaration of runner clashes with your later usage; (2) the proper signature of a thread's start function is void* f(void*) - IOW it takes a single pointer to void not an array of pointers to void.
I am trying to create threads with the pthread library. Compilation is fine with
gcc -o -pthread file file.c
but when I run the code, I get a segmentation fault. I am not sure what the problem is. I tried to execute the code that was given in the textbook to try and learn but I am lost right now. Can anyone help? The code is below... very basic, yes but please hlep me out.
#include<stdio.h>
#include<pthread.h>
int sum;
void *runner(void *param);
int main (int argc, char *argv[])
{
pthread_t tid;
pthread_attr_t attr;
//printf("Am I here..?\n");
if (argc!=2)
{
fprintf(stderr, "usage: a.out ...\n");
return -1;
}
if (atoi(argv[1] < 0))
{
fprintf(stderr, "%d must be >= 0\n", atoi(argv[1]));
return -1;
}
pthread_attr_init(&attr);
pthread_create(&tid, &attr, runner, argv[1]);
pthread_join(tid, NULL);
printf("sum = %d\n", sum);
}
void *runner(void *param)
{
extern int sum;
int i, upper=atoi(param);
sum=0;
for(i=1; i<= upper; i++)
sum+=i;
pthread_exit(0);
}
Please turn on, and examine carefully, your compiler's warnings.
You're not including stdlib.h, so atoi is undeclared, and you're not returning anything from runner but you've declared it as returning a void*.
But the main problem is this line:
if (atoi(argv[1] < 0))
argv[1] < 0 will evaluate to 0 or 1, which are not what you want as an argument to atoi. What you wanted is:
if (atoi(argv[1]) < 0)
It's more than likely that your compiler would have indicated all these problems if the right warnings were enabled.
You have misplaced the bracket:
Change:
if (atoi(argv[1] < 0))
to:
if (atoi(argv[1]) < 0)
I am programming with pthread on linux(Centos)? I wanna to threads sleep a short time to wait for something. I am trying to use sleep(), nanosleep(), or usleep() or maybe something can do that. I want to ask that: Do sleep functions sleep all threads or just the one who call it? Any advices or references would be appreciate.
void *start_routine () {
/* I just call sleep functions here */
sleep (1); /* sleep all threads or just the one who call it?
what about nanosleep(), usleep(), actually I
want the threads who call sleep function can
sleep with micro-seconds or mili-seconds.
*/
...
}
int main (int argc, char **argv) {
/* I just create threads here */
pthread_create (... ...);
...
return 0;
}
My test program:
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <unistd.h>
void *start_routine (void *j) {
unsigned long sum;
int i;
int jj;
jj = (int)j;
do {
sum = 1;
for (i=0; i<10000000; i++) {
sum = sum * (sum+i);
}
if (jj == 0) {
printf ("\033[22;33m[jj%d.%ld]\t", jj, sum);
sleep(1);
}
else {
printf ("\033[22;34m[jj%d.%ld]\t", jj, sum);
}
}while (1);
pthread_exit((void *)0);
}
int main(int argc, char *argv[])
{
cpu_set_t cpuset;
pthread_t thread[2];
int i;
i = 0;
CPU_ZERO(&cpuset);
CPU_SET(i, &cpuset);
pthread_create (&thread[0], NULL, start_routine, (void *)i);
pthread_setaffinity_np(thread[0], sizeof(cpu_set_t), &cpuset);
i = 1;
CPU_ZERO(&cpuset);
CPU_SET(i, &cpuset);
pthread_create (&thread[1], NULL, start_routine, (void *)i);
pthread_setaffinity_np(thread[1], sizeof(cpu_set_t), &cpuset);
pthread_exit (NULL);
}
The standard spells it:
The sleep() function shall cause the calling thread to be
suspended from execution until ....
The linux one is just as clear:
sleep() makes the calling thread sleep until...
There are however a few erroneous references which maintain otherwise. linux.die.net used to state sleep causes the process to wait.
Just the thread which calls the function.