Runtime error- POSIX threads - c

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)

Related

Thread Program on Linux (Posix Thread)

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.

My pid identifier not expected

So for school I got this exercise where I need to make a program that calculates if a number is a prime number or not. This program should make use of parent and child processes, and strtoul should be used to convert the argv to a unsigned long.
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
void checkprime(unsigned long num);
int main(int argc, char *argv, char *env)
{
strtoul(argv, NULL, 0);
pid_t pid = fork();
if(pid == 0)
{
unsigned long number;
printf("\nGive number to check: \n");
scanf("%lu",&number);
checkprime(number);
}
else if(pid < 0)
{
perror("Fork Failed!");
}
else
{
int status = -1, result;
waitpid(pid, &status, 0);
result = WEXITSTATUS(status);
if(result == 1)
{
printf("this is a prime number\n");
}
else if(status < 0)
{
perror("Something Failed");
}
else
{
printf("this is not a prime number\n");
}
}
return 0;
}
void checkprime(unsigned long num)
{
int i;
for(i = 2; i < num; i++)
{
if(num % i == 0)
{
exit(0);
}
}
exit(1);
}
So when I try to compile this it says: line 13: identifier not expected. Error code 1.
The code on line 13 says: pid_t pid = fork();
Now my question is: Why do i get that error?
Its fixed, thanks everyone for the help. I appreciate it.
Some old versions of compilers accept C89 (not C99 or C11) as the default C dialect. You want C99 (since you have a declaration after a statement) at least.
If you use some old version of GCC on some old Linux distribution, try compiling with gcc -std=gnu99 -Wall -Wextra -g where -std=gnu99 sets the C dialect (you could also use -std=c99 or better), -Wall -Wextra asks for warnings, -g wants debug information (in DWARF, for the gdb debugger). Better yet, upgrade your GCC to a recent version (like GCC 7 in November 2017) whose default is C11 with GNU extensions.
Or put the declaration
pid_t pid= 0;
(I prefer to systematically initialize variables in C)
before the statements
strtoul(argv, NULL, 0); //useless call, you need to store the result
pid= fork();
The compiler is telling you it didn't expect to encounter an identifier pid_t at that line since the previous line wasn't an identifier. You need to declare your variables at the top of the scope, and put other code below that. You could either do this
int main(int argc, char *argv, char *env)
{
long int val=strtoul(argv, NULL, 0);
pid_t pid = fork();
...
or
int main(int argc, char *argv, char *env)
{
pid_t pid = fork();
strtoul(argv, NULL, 0);
...
But you're missing the value returned from strtol
You can use make shorter prime finder loop by changing, i < num to i < num/2.
This is one of standards for main() arguments:
(int argc, char **argv)
Turn on gcc flag: -Wall to see all warnings in code.
As #cleblanc said in one of answer, store return value of strtoul() to a varibale long int val = strtoul(argv[1], NULL, 0);.
we pass number for check, from command line arguments,
argv[1] refers to number when we run program with
./prime 15
Code
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void checkprime(unsigned long num);
int main(int argc, char **argv)
{
long int val = strtoul(argv[1], NULL, 0);
pid_t pid = fork();
if(pid == 0){
checkprime(val);
}
else if(pid < 0){
perror("Fork Failed!");
}
else{
int status = -1, result;
waitpid(pid, &status, 0);
result = WEXITSTATUS(status);
if(result == 1){
printf("Prime\n");
}
else if(status < 0){
perror("Something Failed");
}
else{
printf("Not prime\n");
}
}
return 0;
}
void checkprime(unsigned long num)
{
int i;
for(i = 2; i < num/2; i++){
if(num % i == 0){
exit(0);
}
}
exit(1);
}
Compile, Run
gcc -Wall prime.c -o prime
./prime 15

Get/Set the pthread scheduling policy in Linux

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

Incomprehensible result of a multithread code

I will start a C Programming project that will be used multithread. Before I start the project, I have written a code for practice. My purpose is to see how mutex and threads works. However it is not work properly. Here is the code:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
pthread_mutex_t myMutex;
char myStrings[100][30];
int i=0;
void *PrintThread1()
{
printf("this is initial of FIRST Thread\n");
for (int j=0; j<33; j++) {
pthread_mutex_lock(&myMutex);
strcpy(myStrings[i], "This is FIRST thread");
i++;
pthread_mutex_unlock(&myMutex);
}
pthread_exit(NULL);
}
void *PrintThread2()
{
printf("this is initial of SECOND Thread\n");
for (int j=0; j<33; j++) {
pthread_mutex_lock(&myMutex);
strcpy(myStrings[i], "This is SECOND thread");
i++;
pthread_mutex_unlock(&myMutex);
}
pthread_exit(NULL);
}
void *PrintThread3()
{
printf("this is initial of THIRD Thread\n");
for (int j=0; j<33; j++) {
pthread_mutex_lock(&myMutex);
strcpy(myStrings[i], "This is THIRD thread");
i++;
pthread_mutex_unlock(&myMutex);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t firstThread, secondThread, thirdThread;
//pthread_attr_t attr;
pthread_mutex_init(&myMutex, NULL);
//pthread_attr_init(&attr);
//pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
int ft;
ft = pthread_create(&firstThread, NULL, PrintThread1(), NULL);
if (ft){
printf("ERROR; return code from pthread_create() is %d\n", ft);
exit(-1);
}
ft = pthread_create(&secondThread, NULL, PrintThread2(), NULL);
if (ft){
printf("ERROR; return code from pthread_create() is %d\n", ft);
exit(-1);
}
ft = pthread_create(&thirdThread, NULL, PrintThread3(), NULL);
if (ft){
printf("ERROR; return code from pthread_create() is %d\n", ft);
exit(-1);
}
pthread_join(firstThread, NULL);
pthread_join(secondThread, NULL);
pthread_join(thirdThread, NULL);
pthread_mutex_destroy(&myMutex);
for (int j=0;j<100; j++) {
printf("String[%d] = %s\n",j,myStrings[j]);
}
printf("\n");
pthread_exit(NULL);
return -1;
}
When I execute this code, my result is:
this is initial of FIRST Thread
Program ended with exit code: 0
I can't figure out the mistake.
ft = pthread_create(&firstThread, NULL, PrintThread1(), NULL);
should read
ft = pthread_create(&firstThread, NULL, PrintThread1, NULL);
and similarly for all your pthread_create calls.
To use pthread_create, you need to pass it the address of a thread-start routine, which you do in C by writing the name of a function without the function-call parentheses.
As you have written it, you call the intended thread-start routine, on the main thread, and pass whatever it returns to pthread_create to be the thread-start routine. But it never returns, because it calls pthread_exit, which (since pthread_create hasn't been called yet, so there is only one thread) terminates the entire program.
Unfortunately, you have to crank the warnings way up before the compiler will catch this mistake, and even then it's not super clear what the problem is:
$ gcc -std=c99 -Wall -pedantic -pthread test.c
test.c: In function ‘main’:
test.c:60:45: warning: ISO C forbids passing argument 3
of ‘pthread_create’ between function pointer and ‘void *’ [-Wpedantic]
ft = pthread_create(&firstThread, NULL, PrintThread1(), NULL);
^
Without -pedantic, no complaint.

Seg fault (core dumped) after pthread_join in C

I keep getting a seg fault (core dump) after pthread_join in my program. It prints out the expected result just fine, but seg faults when joining the thread. I have looked at several other discussions on this topic, but none of the suggested solutions seem to work in my case. Here is what my compile command looks like (no compile warnings or errors):
$ gcc -Wall -pthread test.c -o test
Here is the output:
$ ./test
1 2 3 4 5 6 7 8 9 10
Segmentation fault (core dumped)
And here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int array[10];
void *fillArray(int *size) {
int i;
for (i = 0; i < *size; i++) {
array[i] = i+1;
}
return NULL;
}
int main (int argc, char *argv[])
{
int i, rc;
int size = 10;
pthread_t thread;
void *res, *end;
//initialize the array
for (i = 0; i < size; i++) {
array[i] = 0;
}
rc = pthread_create(&thread, NULL, fillArray(&size), &res);
if (rc != 0) {
perror("Cannot create thread");
exit(EXIT_FAILURE);
}
//print the array
for (i = 0; i < size; i++) {
if (array[i] != -1)
printf("%d ", array[i]);
}
printf("\n");
rc = pthread_join(thread, &end);
if (rc != 0) {
perror("Cannot join thread");
exit(EXIT_FAILURE);
}
return 0;
}
Any ideas what could be the cause?
This doesn't compile for me: It fails with
dummy.cpp: In function ‘int main(int, char**)’:
dummy.cpp:29: error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
dummy.cpp:29: error: initializing argument 3 of ‘int pthread_create(_opaque_pthread_t**, const pthread_attr_t*, void* (*)(void*), void*)’
Which is because you're actually calling fillArray and passing its result to pthread_create, rather than passing the function pointer. I expect your code will need to look more like this (UNTESTED!) : (Note I changed signature of fillArray, created data struct type to pass to fillArray, changed how pthread_create is called)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int array[10];
struct fillArrayData {
int * array;
int size;
int * result;
};
void *fillArray(void *void_data) {
fillArrayData * data = (fillArray*)void_data;
for (int i = 0; i < data.size; i++) {
data.array[i] = i+1;
}
//You could fill in some return info into data.result here if you wanted.
return NULL;
}
int main (int argc, char *argv[])
{
int i, rc;
int size = 10;
pthread_t thread;
void *res, *end;
//initialize the array
for (i = 0; i < size; i++) {
array[i] = 0;
}
fillArrayData data;
data.array = array;
data.size = 10;
rc = pthread_create(&thread, NULL, fillArray, &data);
if (rc != 0) {
perror("Cannot create thread");
exit(EXIT_FAILURE);
}
//print the array
for (i = 0; i < size; i++) {
if (array[i] != -1)
printf("%d ", array[i]);
}
printf("\n");
rc = pthread_join(thread, &end);
if (rc != 0) {
perror("Cannot join thread");
exit(EXIT_FAILURE);
}
return 0;
}
Error in
Calling function pointer
passing parameter to thread handler
In pthread prototype of pthread_create below
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
1st argument - pthread_variable
2nd argument - thread attrubutes
3rd argument - thread handler(function pointer name)
4th argument - variable need to pass thread handler.
In 4th argument - if two thread want to share single variable, then create global variable, and the pass this variable when creating thread.
sample program:
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
further details here

Resources