I can not use my global variable pointer buffer1 in a thread. Give me Segmentation fault. Why? Thank you.
# include <stdio.h>
# include <stdlib.h>
# include <pthread.h>
# include <malloc.h>
# include <semaphore.h>
int **buffer1;
int **crear_buffer(int tamano) {
int i;
int **matriz = (int **)malloc(sizeof(int *) * tamano);
for (i = 0; i < tamano; i++) {
matriz[i] = (int *)malloc(sizeof(int) * 2);
}
return matriz;
}
void *productor(void *arg){
int num_pares= *((int *) arg);
int i=0;
int cont=0;
while(cont<num_pares){
int primero=5;
int segundo=8;
if (primero<=segundo){
buffer1[i][0]=primero;
buffer1[i][1]=segundo;
}
else{
buffer1[i][0]=segundo;
buffer1[i][1]=primero;
}
i=(i+1)%tamano_buffer1;
cont++;
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]){
sscanf(argv[1], "%d", &tamano_buffer1);
sscanf(argv[2], "%d", &N);
int **buffer1=crear_buffer(tamano_buffer1);
pthread_t tid_productor;
pthread_create(&tid_productor, NULL, productor,(void *) &N);
pthread_join(tid_productor, NULL);
return 0;
}
Because you never assigned it:
This is a NEW local variable named buffer1:
int **buffer1=crear_buffer(tamano_buffer1);
This would have been assigning to your existing global variable:
buffer1=crear_buffer(tamano_buffer1);
Related
I am having some trouble understanding this code since I am new to pthread programming. From what I understand, we create N threads and execute the run function on them, which only prints the thread number. Am I missing something?
Is there any advantage of using snprintf (with buffers) over printf in this particular case? Could this program be improved any further?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static int N = 5;
static void* run(void *arg)
{
int *i = (int *) arg;
char buf[123];
snprintf(buf, sizeof(buf), "thread %d", *i);
return buf;
}
int main(int argc, char *argv[])
{
int i;
pthread_t *pt = NULL;
for (i = 0; i < N; i++) {
pthread_create(pt, NULL, run, &i);
}
return EXIT_SUCCESS;
}
First of all, your threads return garbage. Deferencing the pointer returned would be Undefined Behaviour because it points to storage that no longer exists after the function returns. Good thing nothing used the pointer.
Next, the threads don't print anything because snprintf outputs to an array, not stdout.
Furthermore, the threads would print garbage if you switched to printf because the same pointer is passed to to all threads.
And that's assuming the threads have a chance to run since main doesn't wait for the threads to finish. You gotta join them.
Fixed:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define N 5
static void *run(void *arg) {
size_t job = *(size_t*)arg;
printf("Job %zu\n", job);
return NULL;
}
int main(int argc, char *argv[]) {
size_t jobs[N];
pthread_t threads[N];
for (size_t i=0; i<N; ++i) {
jobs[i] = i;
pthread_create(threads+i, NULL, run, jobs+i);
}
for (size_t i=0; i<N; ++i) {
pthread_join(threads[i]);
}
return EXIT_SUCCESS;
}
It's also common to pass an integer cast to a pointer.
#include <inttypes.h>
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
static void *run(void *arg) {
size_t job = *(uintptr_t*)arg;
printf("Job %" PRIuPTR "\n", job);
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t threads[N];
for (uintptr_t i=0; i<N; ++i) {
pthread_create(threads+i, NULL, run, (void*)i);
}
for (uintptr_t i=0; i<N; ++i) {
pthread_join(threads[i]);
}
return EXIT_SUCCESS;
}
I am working on a function that creates a thread and calculates the Fibonacci sequence to a certain user inputted value. For example, if a user enters 5, the output will be: 0 1 1 2 3 5
However, the sequence must be calculated in the created thread, and the results have to be printed out after the thread is exited.
I can create the thread and calculate the sequence, but I need to pass the array fibSequence[] back to the original thread using pthread_exit and pthread_join. I am having trouble figuring out the syntax and can't find any examples of people passing arrays through.
What I have so far:
I created a function fib_runner() that is called by a newly created thread. The Fibonacci sequence is created and placed into the array fibSequence[]. I need to pass this back through to the main function. I am temporarily printing out the sequence in the function, but it should be printed in the main.
Thank you!
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* fib_runner(void* arg)
{
int *limit_ptr = (int*) arg;
int limit = *limit_ptr;
int fibSequence[limit];
int size = sizeof(fibSequence)/sizeof(fibSequence[0]);
printf("Size: %d\n", size);
fibSequence[0] = 0;
fibSequence[1] = 1;
for (int i = 2; i <= size; i++)
{
fibSequence[i] = fibSequence[i-1] + fibSequence[i-2];
}
for (int i = 0; i <= size; i++)
{
printf("%d ", fibSequence[i]);
}
pthread_exit(0);
}
int main(int argc, char **argv)
{
int limit;
printf("Enter Number: ");
scanf("%d", &limit);
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, fib_runner, &limit);
pthread_join(tid, NULL);
}
Currently, the array is a local variable, so it would go out of scope when the function exits. You need to dynamically allocate memory for it instead:
int *fibSequence = malloc(sizeof(int) * limit);
Then return this pointer from the function:
return fibSequence;
In your main function, you then pass the address of a pointer to receive this value. Then you can print the content of the array. When you're done, be sure to free it:
int *fibSequence;
pthread_join(tid, (void **)&fibSequence);
for (int i = 0; i < limit; i++)
{
printf("%d ", fibSequence[i]);
}
free(fibSequence);
Also, you don't need size in your thread function, since it is the same as limit, and the way you currently calculate it won't work anyway since you now have a pointer instead of an array. Your loop limit in fib_runner also goes one past the end of the array. The exit condition should be i < size, not i <= size.
you have to pass in a value of void * to pthread_exit which is pthread_exit(( void * ) &fibSequence, once that function is called the passed in value will populate the second argument to pthread_join, the second argument will be a pointer to a pointer void ** it will hold the values passed in to pthred_exit
All the threads running within a process share the same address space, file descriptors, stack and other process related attributes.
Threads are sharing memory by definition, they do not own anything except stack and local variables;
If you make fibSequence[limit] global then all threads will have access to it.
You can also declare fibSequence[limit] on the stack in main and pass pointer to it to your thread.
To pass multiple arguments it is convenient to wrap them up in a structure.
The solutions below employ:
struct arg_struct {
int limit;
int *ptrFib;
}args;
Program:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct arg_struct {
int limit;
int *ptrFib;
}args;
void* fib_runner(void* arg)
{
struct arg_struct *a = (struct arg_struct *) arg;
int size = a->limit;
int * fibSequence = a->ptrFib;
fibSequence[0] = 0;
fibSequence[1] = 1;
for (int i = 2; i <= size; i++){
fibSequence[i] = fibSequence[i-1] + fibSequence[i-2];
}
pthread_exit(0);
}
int main(int argc, char **argv)
{
int limit;
printf("Enter Number: ");
scanf("%d", &limit);
int fibSequence[limit];
struct arg_struct argF;
argF.limit = limit;
argF.ptrFib = fibSequence;
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, fib_runner, &argF);
pthread_join(tid, NULL);
for (int i = 0; i <= limit; i++){
printf("%d ", fibSequence[i]);
}
}
Output:
Enter Number: 5
0 1 1 2 3 5
The solution with global variable argF is of course possible but it is less elegant.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct arg_struct {
int limit;
int *ptrFib;
}args;
struct arg_struct argF;
void* fib_runner()
{
int size = argF.limit;
int * fibSequence = argF.ptrFib;
fibSequence[0] = 0;
fibSequence[1] = 1;
for (int i = 2; i <= size; i++){
fibSequence[i] = fibSequence[i-1] + fibSequence[i-2];
}
pthread_exit(0);
}
int main(int argc, char **argv)
{
int limit;
printf("Enter Number: ");
scanf("%d", &limit);
int fibSequence[limit];
argF.limit = limit;
argF.ptrFib = fibSequence;
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, fib_runner, NULL);
pthread_join(tid, NULL);
for (int i = 0; i <= limit; i++){
printf("%d ", fibSequence[i]);
}
}
I'm tired about this problem. I use valgrind also. but I don't know why. Please find what is the problem in my code.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static pthread_t *tid=NULL;
static int **data3=NULL;
typedef struct _Thdata
{
int *data;
int size;
int nthread;
} Thdata;
Thdata *tdata=NULL;
void *bubble(void *d){
Thdata *arr =(Thdata *)d;
int i,j,tmp;
int n=arr->size;
printf("thread #=%d n=%d\n",arr->nthread,n);
for(i=0;i<n;i++){
for(j=0;j<n-1;j++){
if((arr->data[j])>(arr->data[j+1]))
{
tmp = (arr->data[j]);
(arr->data[j])=(arr->data[j+1]);
(arr->data[j+1])=tmp;
}
}
}
for(j=0;j<n;j++)
printf("%d ",(arr->data[j]));
printf("\n");
pthread_exit((void *)1);
}
int main(int argc, char **argv){
FILE * fd;
int i,j;
int data[100];
int tcount = atoi(argv[1]);
int n = 100/tcount;
int err;
void *b;
//dynamic data
tid = (pthread_t *)malloc(tcount* sizeof(pthread_t));
data3 = (int **)malloc(tcount *sizeof(int*));
for( i=0; i<tcount; i++)
data3[i] = (int *)malloc((100/tcount) *sizeof(int));
tdata = (Thdata *)malloc(tcount*sizeof(Thdata));
for(i=0;i<tcount; i++) {
tdata[i].data =(int *)malloc(n*sizeof(int));
}
//dynamic data end
fd = fopen("data.txt", "r");
printf("tcount = %d n=%d\n",tcount,n);
// origin data
for(i =0; i<100;i++)
{
fscanf(fd, "%d",&data[i]);
printf("%d ", data[i]);
}
printf("\n");
for(j=0;j<tcount;j++){
for(i=0;i<n;i++){
data3[j][i]=data[n*j+i];
printf("%d ",data3[j][i]);
//tdata[j].data[i]=data[j][i];
}
printf("\n");
tdata[j].data=data3[j];
tdata[j].size=n;
tdata[j].nthread=0;
}
for(j=0;j<tcount;j++){
for(i=0;i<n;i++){
printf("%d ",tdata[j].data[i]);
}
printf("tdata[%d].size = %d",j,tdata[j].size);
printf("\n");
}
for(i =0; i<tcount;i++)
{
err=pthread_create(&tid[i],NULL,bubble,(void *)&tdata[i]);
if(err != 0)
printf("creat thread error");
tdata[i].nthread=i;
}
for(i=0;i<tcount;i++)
pthread_join(tid[i],&b);
for(i=tcount-1;i>=0;i--){
free(tdata[i].data);
}
free(tdata);
for(int i=tcount-1; i>=0; i--)
free(data3[i]);
free(data3);
free(tid);
fclose(fd);
return 0;
}
You assigned data3[j] to tdata[j].data as
tdata[j].data=data3[j];
so passing both of them to free() will cause double-free error as you said.
If you want to only copy pointers and copying values in data3[j] isn't needed, remove the part
for(i=0;i<tcount; i++) {
tdata[i].data =(int *)malloc(n*sizeof(int));
}
because the variable tdata[i].data will be overwritten later and memory leak will be caused. Also remove the part
for(i=tcount-1;i>=0;i--){
free(tdata[i].data);
}
because it will cause double-free error as descrived above.
I using first time the HEADERS in c so I'm not understanding it well.
main.c
#include <stdio.h>
#include <stdlib.h>
#include "kibe.h"
int main()
{
int a[5],n,i;
beolvas(a,n,"be.txt");
kiir(a,n);
return 0;
}
kibe.h
#ifndef KIBE_H_INCLUDED
#define KIBE_H_INCLUDED
void beolvas(int*, int, const char *);
void kiir(int*, int);
#endif // KIBE_H_INCLUDED
kibe.c
#include <stdio.h>
#include <stdlib.h>
void beolvas(int *a,int n,const char * file)
{
int i;
FILE * fin;
fin = fopen("be.txt", "rt");
fscanf(fin,"%i",&n);
a = (int*)malloc(n*sizeof(int));
for(i = 0; i < n; ++i){
fscanf(fin,"%i",&a[i]);
}
free(a);
}
void kiir(int *a,int n)
{
int i;
for(i = 0; i < n; ++i){
printf("%i ",a[i]);
}
}
The problem is that I get memory garbage every time and the file contains five numbers which must be read and written to monitor. If I write the void kiir is code to void beolvas function it works well.
You allocate dynamic memory in your function beolvas but you never pass it out of the function. Your parameters a and n have to be output parameters, so you have to change your function signature. Apart form this use fclos to close the file. Adapt your code like this:
kibe.c
void beolvas( int **a, int *n, const char * file )
// ^^ ^ output paramters a and n
{
FILE * fin;
fin = fopen("be.txt", "rt");
fscanf( fin, "%i", n ); // read number of elements
// ( n is a pointer to an int )
*a = malloc( *n * sizeof(int) ); // allocate memors
for ( int i = 0; i < n; ++i)
{
fscanf(fin,"%i",(*a)+i); // read one element
// ( *a is the pointer to the dynamic memory,
// so (*a)+i is a pointer to (*a)[i] )
}
fclose(fin);
}
kibe.h
void beolvas( int**, int* , const char *);
main.c
int main()
{
int a* = NULL;
int n = 0;
beolvas( &a, &n,"be.txt");
// ^ ^
kiir( a, n );
free(a); // free the memory which was allocated inside function beolvas
return 0;
}
I am attempting on creating multiple threads that each thread calculates a prime. I am trying to pass a second argument to a function using thread create. It keeps throwing up errors.
void* compute_prime (void* arg, void* arg2)
{
here is my main() with the create thread. &primeArray[i] after &max_prime is giving me the errors.
for(i=0; i< num_threads; i++)
{
primeArray[i]=0;
printf("creating threads: \n");
pthread_create(&primes[i],NULL, compute_prime, &max_prime, &primeArray[i]);
thread_number = i;
//pthread_create(&primes[i],NULL, compPrime, &max_prime);
}
/* join threads */
for(i=0; i< num_threads; i++)
{
pthread_join(primes[i], NULL);
//pthread_join(primes[i], (void*) &prime);
//pthread_join(primes[i],NULL);
//printf("\nThread %d produced: %d primes\n",i, prime);
printf("\nThread %d produced: %d primes\n",i, primeArray[i]);
sleep(1);
}
the error i get is:
myprime.c: In function âmainâ:
myprime.c:123: warning: passing argument 3 of âpthread_createâ from incompatible pointer type
/usr/include/pthread.h:227: note: expected âvoid * (*)(void *)â but argument is of type âvoid * (*)(void *, void *)â
myprime.c:123: error: too many arguments to function âpthread_createâ
It works fine if i take out the second argument.
You can only pass a single argument to the function that you are calling in the new thread. Create a struct to hold both of the values and send the address of the struct.
#include <pthread.h>
#include <stdlib.h>
typedef struct {
//Or whatever information that you need
int *max_prime;
int *ith_prime;
} compute_prime_struct;
void *compute_prime (void *args) {
compute_prime_struct *actual_args = args;
//...
free(actual_args);
return 0;
}
#define num_threads 10
int main() {
int max_prime = 0;
int primeArray[num_threads];
pthread_t primes[num_threads];
for (int i = 0; i < num_threads; ++i) {
compute_prime_struct *args = malloc(sizeof *args);
args->max_prime = &max_prime;
args->ith_prime = &primeArray[i];
if(pthread_create(&primes[i], NULL, compute_prime, args)) {
free(args);
//goto error_handler;
}
}
return 0;
}
In case of std::thread, the user can pass arguments to the thread function in the following method
std::thread(funcName,arg1,arg2);
for instance,
//for a thread function,
void threadFunction(int x,int y){
std::cout << x << y << std::endl;
}
// u can pass x and y values as below
std::thread mTimerThread;
mTimerThread = std::thread(threadFunction,1,12);
This is the code of Manakarse , everything is really good but you need a
pthread_join(thread[i],NULL)
just to be sure all of threads will successfully execute before end of main thread("main will "waiting" while all of threads aren't finished yet)
;
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct
{
int stop_flag;
char name[30];
} _process_data;
typedef struct
{
int meter_no;
int port_no;
} _process_control;
typedef struct
{
_process_data *process_data;
_process_control *process_control;
} compute_prime_struct;
void *compute_prime (void *args)
{
compute_prime_struct *actual_args = args;
printf("actual_args->process_data->stop_flag [%d]\n",actual_args->process_data->stop_flag);
printf("actual_args->process_data->name [%s]\n",actual_args->process_data->name);
printf("actual_args->process_control->meter_no [%d]\n",actual_args->process_control->meter_no);
printf("actual_args->process_control->port_no [%d]\n",actual_args->process_control->port_no);
free(actual_args);
return 0;
}
void fill_data(_process_data *process_data,_process_control *process_control)
{
process_data->stop_flag=1;
process_data->name[0]='P';
process_control->meter_no=6;
process_control->port_no=22;
pthread_t tid;
compute_prime_struct *args = malloc(sizeof (*args));
args->process_data = malloc(sizeof (*args->process_data));
args->process_control = malloc(sizeof (*args->process_control));
memcpy (args->process_data, process_data, sizeof (args->process_data));
memcpy (args->process_control, process_control, sizeof (*args->process_control));
if(pthread_create(&tid, NULL, compute_prime, args))
{
free(args);
printf("Error here");
}
sleep(1);
}
int main()
{
_process_data process_data;
_process_control process_control;
fill_data(&process_data,&process_control);
return 0;
}