There are 2 structures (2 dynamic arrays), each with its own data set. There was a need to transfer one of the functions to the stream using pthread_create (the change function).

I can not understand how to transfer references to these 2 structures to this function (in the stream) so that I can perform some operations on these structures and with these changes I can continue to work in the main program?

Thank.

Sample program.

#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include <string.h> #include <inttypes.h> struct strc { char str[60]; int uid; struct strc *prev; }; struct param { struct stack *elma; struct stack *elmb; }; struct stack *add(struct stack **base, char *line,int uid) { struct stack *element=(struct stack*)malloc(sizeof(struct stack)); element->prev=*base; strcpy(element->data,line); element->uid=uid; return element; } int search(struct stack *base,char *str) { while (base!=NULL) {if (strcmp(base->data,str)==0) return base->uid; base=base->prev;} return 0; } void * change(void *arg) { struct param *data=arg; *data.elma=add(data.elma,"chips",5); *data.elmb=add(data.elmb,"volvo",2); } int main() { int uid; pthread_t thread; struct strc *elma=NULL; struct strc *elmb=NULL; struct param *arg; arg->elma=elma; arg->elmb=elmb; if (pthread_create(&thread, NULL, change, &arg) != 0) {return -1;} uid=search(elma,"chips"); printf("%i",uid); uid=search(elmb,"volvo"); printf("%i",uid); } 
  • At least it is worth making an example that compiles. In general, you most likely search() is called before the end of change() . Need synchronization of threads. For example, you can call pthread_join () - avp

4 answers 4

Corrected your example to a working condition.

 #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include <string.h> #include <inttypes.h> #include <pthread.h> struct stack { char data[60]; int uid; struct stack *prev; }; struct param { struct stack **elma; struct stack **elmb; }; struct stack *add(struct stack **base, char *line,int uid) { struct stack *element=(struct stack*)malloc(sizeof(struct stack)); element->prev=*base; strcpy(element->data,line); element->uid=uid; return element; } int search(struct stack *base,char *str) { while (base!=NULL) { if (strcmp(base->data,str)==0) return base->uid; base=base->prev; } return 0; } void * change(void *arg) { struct param *data=arg; *(data->elma) = add(data->elma, "chips", 5); *(data->elmb) = add(data->elmb, "volvo", 2); *(data->elma) = add(data->elma, "flips", 15); *(data->elmb) = add(data->elmb, "ford", 21); } int main() { int uid; pthread_t thread; struct stack *elma=NULL; struct stack *elmb=NULL; struct param arg; arg.elma=&elma; arg.elmb=&elmb; if (pthread_create(&thread, NULL, change, &arg) != 0) exit((puts("Can't create thread"), 1)); // тут делаете что-то полезное, \ пока не понадобятся данные из change() if (pthread_join(thread, 0)) exit((puts("Can't join"), 2)); uid=search(elma,"chips"); printf("chips: %i\n",uid); uid=search(elmb,"volvo"); printf("volvo: %i\n",uid); uid=search(elma,"flips"); printf("flips: %i\n",uid); uid=search(elmb,"bmw"); printf("bmw: %i\n",uid); } 

In essence, I replaced the transfer in change() pointers to "stacks" to the transfer of addresses of these pointers ( param structure), because in main you explicitly use elma and elmb to refer to search() and added a call to pthread_join to wait for the completion of the stacks
(of course, added #include <pthread.h> ).

 avp@wubu:hashcode$ gcc pt.c -lpthread && ./a.out chips: 5 volvo: 2 flips: 15 bmw: 0 avp@wubu:hashcode$ 
  • I am very grateful, everything worked and it became clear now that where and how)) Thank you. - nerik

Collect the pointers in one structure and pass a pointer to it. Something like

 struct param { struct strc * first; struct strc * second; }; struct param p; p.first = elma; p.second = elmb; 

and pass the pointer to p .

Like that.

  • Done, passed to pthread_create (& thread, NULL, change, (void *) p); Then I try to add data in the function: data-> str = add (& data-> str, "Petrov", 5); After starting, I get the Segmentation fault - nerik
  • Is memory allocated for structures, for example? How can you judge what you are doing without having a normal code? Give a minimal reproducible example, let's see ... - Harry
  • updated the source code of the program in question - nerik
  • one
    @nerik Well, you immediately! without departing from the cash! struct param * arg; arg-> elma = elma; arg-> elmb = elmb; those. you dereference an uninitialized pointer . - Harry
  • I don't understand pointers yet. Can you modify to understand by example? - nerik

I can not understand how you can pass links to these 2 structures in this function (in the stream),

The principal difference between the PROCESS and the FLOW (thread) is that the processes work in isolated address spaces, and all the threads work in the same (!) Address space. And this means that if you write like this:

 struct data1 { . . . } struct data2 { . . . } void fun1(void *a) { . . . } void fun2(void *a) { . . . } 

Both data structures will be visible in both functions as globally declared. And you can run both the one and the other function as threads, without passing anything in the parameter lists.

Significantly note: in order for these functions to work with the GENERAL data structure correctly, it is necessary to surround this work with protective barriers - mutexes. But this is a separate topic.

    Using the previous example, we convert two arrays

     typedef struct _data_s data_s; struct _data_s { int ready; int * first; int size_first; int * second; int size_second; }; static gpointer thread_fun(gpointer d) { int rc; data_s * data = (data_s*)d; int * first = data->first; int * second = data->second; int * local_first = g_slice_alloc0(sizeof(int)*data->size_first,); int * local_second = g_slice_alloc0(sizeof(int)*data->size_second);; for(;;){ /*чтение данных*/ rc = g_mutex_trylock(&mutex); if(rc){ rc = data->ready; if(rc){ memmove(local_first,first,data->size_first); memmove(local_second,second,data->size_second); data->ready = FALSE; g_mutex_unlock(&mutex); } else{ g_mutex_unlock(&mutex); g_usleep(10000); continue; } } else{ g_usleep(10000); continue; } /*обработка данных*/ .... /*запись данных*/ g_mutex_lock(&mutex); memmove(first,local_first,data->size_first); memmove(second,local_second,data->size_second); g_mutex_unlock(&mutex); /*если требуется накопление данных*/ g_usleep(TIMEOUT); } g_slice_free1(data->size_first,local_first); g_slice_free1(data->size_second,local_second); return NULL; int main(int argc,char * argv[]) { GThread * thread; data_s data; data.ready = FALSE; data.size_first = 10; data.first = g_slice_alloc0(sizeof(int)*data.size_first); data.size_second = 10; data.second = g_slice_alloc0(sizeof(int)*data.size_second); g_mutex_init(&mutex); thread = g_thread_new("data",thread_fun,&data); for(;;){ g_mutex_lock(&mutex); read(fd1,data.first,data.size_first); read(fd2,data.second,data.size_second); data.ready = TRUE; g_mutex_unlock(&mutex); } g_slice_free1(data.size_first,data.first); g_slice_free1(data.size_second,data.second); return 0; }