简体   繁体   中英

Mixing GCD and pThread leads to weird effects

I have downloaded a multi-platform library I want to use. The library works fine when building a pure C command line application. There are printfs throughout which show exactly what I expected.

I am calling this from iOS Objective-C like this:

dispatch_async() { 
     callbackFunctPtr =  myCallBackFunction; 
     LibrariesRunLoopFunction(); 
}

The library goes off and does stuff which results in pthread_create()s in the C code and then calls back something like this:

void myCallBackFunction(char *text)
{

    NSLog( @"%s", __PRETTY_FUNCTION__ ); 
    dispatch_async( dispatch_get_main_queue(), ^{
      // This line seems to get called sometimes once, sometimes many times.
      [myViewControllerPtr updateUITextViewWith:text];  
    }

}

The thing that I can;t get my head around is that [myViewControllerPtr updateUITextViewWith:text]; seems to get called sometimes once but often several times, and sometimes with corrupted text.

Memory management is all but impossible when passing around char* C strings across threads. You don't know who created the memory, and you don't know when the receiver will be done with it so you can release it.

My guess is that the char * text passed to myCallBackFunction is only valid for the duration of the call, and gets released as soon as the function returned. (It is probably allocated with a malloc() , and released with a call to free() .)

You will need to come up with some method for managing them memory between the different threads.

One approach would be to copy the string in your callback function, then release it from the main thread after you're done with it:

void myCallBackFunction(char *text)
{
    //Create a block of memory for the string copy (plus 1 for the null)
    char *newText = malloc(strlen(text)+1);

    //Copy the string to the newly allocated buffer.
    strcpy(newText, text);
    NSLog( @"%s", __PRETTY_FUNCTION__ ); 
    dispatch_async( dispatch_get_main_queue(), ^{
      // This line seems to get called sometimes once, sometimes many times.
      [myViewControllerPtr updateUITextViewWith:newText];
      //free the text buffer once the view controller is done with it.
      free(newText);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM