Reputation: 111
This is the first time that i am using threads and I started with a simple program. The program takes n
arguments and creates n-2
threads. The thing is I get a segmentation fault and I don't know why.
Here's the code:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
void *
removeBytes (int i, char* argv[])
{
printf ("%d, %s\n", i, argv[i]);
return NULL;
}
int main (int argc, char *argv[])
{
pthread_t threads[argc - 3];
int err;
int i;
int *ptr[argc - 3];
printf ("argc = %d\n", argc);
for (i = 0; i < argc -3; i++)
{
err =
pthread_create (&(threads[i]), NULL,
removeBytes(i+1,&argv[i+1]), NULL);
if (err != 0)
{
printf ("\nCan't create thread: [%d]", i);
}
else
{
printf ("\nThread created successfully\n");
}
}
for (i = 0; i < argc - 3; i++)
{
pthread_join (threads[i], (void **) &(ptr[i]));
printf("pthread_join - thread %d",i);
}
return 0;
}
Example: my program is called mythread
so when I run it ./mythread f1 f2 f3 f4 f5 f6
the output is:
argc = 6
1,f2
Thread created successfully
2,f4
Thread created successfully
3, (null)
And why does it take f2
as argv[1]
and f4
as argv[2]
?
UPDATE:
typedef struct{
int i;
char* argv;
}Data;
void* removeBytes(void* arg){
Data* data = (Data*)arg;
printf("%d, %s\n",data->i, data->argv);
free(data);
return NULL;
}
int main(int argc, char** argv){
Data* data;
pthread_t threads[argc-3];
int i;
int err;
for(i=0; i < argc-3;i++){
data = (Data*)malloc(sizeof(Data));
data->i=i+1;
data->argv=argv[i+1];
err = pthread_create(&(threads[i]),NULL,removeBytes,data);
if(err != 0){
printf("\nCan't create thread %d",i);
}
else{
printf("Thread created successfully\n");
}
}
return 0;
}
for ./mythread f1 f2 f3 f4 f5 f6 f7 f8 the output is:
5 x "Thread created successfully". It doesn't print i or argvi[i].
Upvotes: 1
Views: 9341
Reputation: 53386
With
pthread_create (&(threads[i]), NULL,
removeBytes(i+1,&argv[i+1]), NULL);
You are calling removeBytes()
instead of passing it as parameter.
Also, You can pass only one argument to thread function. So you need to put multiple arguments in a structure. Something like:
struct thread_args {
int i;
char *argv;
}
#your main code
struct thread_args *thargs;
for (i = 0; i < argc -3; i++)
{
thargs = malloc(sizeof(*thargs));
thargs->i = i+1;
thargs->argv = argv[i+1];
err =
pthread_create (&(threads[i]), NULL,
removeBytes, thargs);
if (err != 0)
{
printf ("\nCan't create thread: [%d]", i);
}
else
{
printf ("\nThread created successfully\n");
}
}
#make sure to free up thargs as well.
And update thread function as
void *removeBytes (void *arg)
{
int i;
char *argv;
struct thread_args *thargs = (struct thread_args *) arg;
i = thargs->i;
argv = thargs->argv;
printf ("%d, %s\n", i, argv);
return NULL;
}
Upvotes: 0
Reputation: 1476
It takes f2 as argv[1] and f4 as argv[2] simply because when you pass &argv[i+1] you actually pass pointer to the (i+1)-th element of the array and you also pass i+1 as index.
So if you have argv equals [mythread, f1, f2, f3, f4, f5, f6] at first you'll get [f1, f2, f3, f4, f5, f6] in removeBytes. And when you're accessing i+1 = 1 element you'll get f2. Next time you'll get [f2, f3, f4, f5, f6] and i+1 = 2 so you'll get f4
Upvotes: 0
Reputation: 10698
You're not using pthread_create
correctly :
pthread_create (&(threads[i]), NULL,
removeBytes(i+1,&argv[i+1]), NULL);
Here you're just calling removeBytes()
and passing the result (NULL
) as an argument of pthread_create()
.
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
The third argument should be a pointer to a void* myThread(void*)
function. If you want to pass arguments to your thread, you should use the void*
parameter and pass it as the third argument of pthread_create
.
You could take a look at this
in order to learn how to use the pthread library.
Also, you probably want to to something like this :
typedef struct {
int i;
char* argv;
} Data;
void * removeBytes (void* arg)
{
Data* data = (Data*) arg;
printf ("%d, %s\n", data->i, data->argv);
free(data);
return NULL;
}
And then create the thread like this:
Data* data = (Data*)malloc(sizeof(Data));
data->i = i;
data->argv = argv[i+1];
err = pthread_create (&(threads[i]), NULL, removeBytes, data);
Upvotes: 0
Reputation: 9411
There is problem in
pthread_create (&(threads[i]), NULL,
removeBytes(i+1,&argv[i+1]), NULL);
Syntax of pthread_create
is
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
It takes start routine as a callback. In your case, you are calling removeBytes in main thread that is before spawning and returning NULL. So, callback is NULL.
So, modify your removeBytes accordingly as per your need and call
pthread_create (&(threads[i]), NULL, removeBytes, argv[i+1]);
Upvotes: 0