The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
аргумент типа int для pthread_create в x86_64, !*! Аноним, 24-Янв-10, 22:39  [смотреть все]
Код на С, портирую с x86 на x86_64 многопоточный сервер (точнее, превращаю его в многоплатформенный, чтобы работало и там и там, т.е. например unsigned int => uint32_t и другие вещи), так вот, после accept-a нужно передать сокет (тип int) в поток, делается это последним параметром фунции pthread_create, вот код:

...
socklen_t addr_len;
addr_len = sizeof(fsin);
accepted_socket = accept(s, (struct sockaddr *)&fsin, &addr_len);
....
....
pthread_create(&th, &ta, (void * (*)(void *))parser, (void *)accepted_socket)

вот как объявлена функция pthread_create:

int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg);


И так, так-как в x86_64 тип указатель (void*) это 64-битное число, а int - 32-битное, GCC выдает warning:

pthread_create warning: cast to pointer from integer of different size

Программа работает, и ошибок и быть не может, потому что ничего не вырезается, а наоборот, но вот как лучше всего сделть чтобы этого warning-a не было (это условие заказчика :)) Конечно, можно решить проблему используя еще одну переменную "прокси", но как-то не Ъ.

  • аргумент типа int для pthread_create в x86_64, !*! Michelnok, 23:57 , 24-Янв-10 (1)
    #include <stdint.h>
    ...
    pthread_create(&th, &ta, (void * (*)(void *))parser, (void *)(intptr_t)accepted_socket)
    • аргумент типа int для pthread_create в x86_64, !*! Аноним, 00:20 , 25-Янв-10 (2)
      >#include <stdint.h>
      >...
      >pthread_create(&th, &ta, (void * (*)(void *))parser, (void *)(intptr_t)accepted_socket)

      Спасибо! А можежь объяснить почему нужно два раза делать cast? Почему явное  преобразование из int в void* генерирует warning?

      • аргумент типа int для pthread_create в x86_64, !*! Michelnok, 00:49 , 25-Янв-10 (3)
        > Почему явное преобразование из int в void* генерирует warning?

        Не знаю, покопайтесь на сайте GNU.
        Предполагаю, что есть опасение перед преобразованием потенциально отрицательного 32-битного числа к беззнаковому 64-битному. Кстати, тогда наверное корректнее приводить к uintptr_t, а не к intptr_t. И сначала int в unsigned. Тогда точно враг не пройдет :)

  • аргумент типа int для pthread_create в x86_64, !*! const86, 15:18 , 26-Янв-10 (4)
    >Конечно, можно решить проблему используя еще одну переменную "прокси", но как-то не Ъ.

    По такой логике, Ъ был предыдущий автор, за которым вы сейчас исправляете. Заведите структуру (с одним полем int) и передавайте в поток указатель на неё. Метод работает всегда одинаково и не нужно изобретать каждый раз новые хаки.

    • аргумент типа int для pthread_create в x86_64, !*! Аноним, 20:24 , 26-Янв-10 (5)
      >>Конечно, можно решить проблему используя еще одну переменную "прокси", но как-то не Ъ.
      >
      >По такой логике, Ъ был предыдущий автор, за которым вы сейчас исправляете.
      >Заведите структуру (с одним полем int) и передавайте в поток указатель
      >на неё. Метод работает всегда одинаково и не нужно изобретать каждый
      >раз новые хаки.

      Тогда пришлось бы для каждой структуры делать malloc, потом free (иначе, будет небезопасно передавать всем потокам указатель на одну и ту же переменную (хоть локальную хоть глобальную), так как поток может и не успеть прочитать ее перед тем как она изменится для следующего потока в цикле). А делать malloc и free в программе, в которой до этого динамически выделяемая память не использовалась, я не стал, ведь нужно передать только один парметр.

      P.S.
      Я не очень опытный кодер на С, так что может что-то и недопонимаю ;)




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру