2010-08-15 59 views
1

在pthread_create錯誤

client_sock = accept(server_sock, (struct sockaddr *)&client_name, &client_name_len);   
    if (pthread_create(&newthread , NULL, (void *) accept_request, client_sock) != 0) { 
      perror("pthread_create"); 
    } 

這只是整個腳本的一部分。每次我嘗試編譯它,我得到warning: passing argument 4 of 'pthread_create' makes pointer from integer without a cast

任何想法爲什麼會發生這種情況?提前致謝。

+0

什麼是accept_request? – Anycorn 2010-08-15 00:32:59

回答

5

參數4是client_sock,這是傳遞給accept_request的參數。它有望成爲一個指針,但由於它只是傳遞給你的函數,所以它可以是一個整數而不會造成任何傷害。只需將其投射到void*即可移除警告。

另一方面,第三個參數accept_request應該是接受void*並返回void*的函數指針。您不應該將它投射到void*。最好將accept_request的聲明更改爲符合規範。

void *accept_request(void *client_sock); 
3

我假設client_sock被定義爲「int client_sock」。在這種情況下,你應該寫如下:

if (pthread_create(&newthread , NULL, (void *) accept_request, &client_sock) != 0) { 

然後在accept_request(其中,順便說一句,應該是一個函數採用指針),你會做這樣的:

void *accept_request(void *client_sock_addr) { 
    int client_sock = *((int*) client_sock_addr); 
} 

轉換一個int到( void *)可能不可移植(因爲i​​nt和void *的數據大小不一定相同)。當然,它可能適用於你當前的編譯器......

感謝jiles指出了這點:根據代碼的其餘部分,該地址的值可能會改變(例如,如果圍繞accept構造有一個循環並且2個接受在一個線程創建之前到達)。做到這一點的最好辦法確實是使用malloc分配內存喜歡

int *client_sock_addr=malloc(sizeof(int)); 
*client_sock_addr = accept(server_sock, (struct sockaddr *)&client_name, &client_name_len);   
if (pthread_create(&newthread , NULL, (void *) accept_request, client_sock_addr) != 0) { 
     perror("pthread_create"); 
} 

然後在功能做:

void *accept_request(void *param) { 
    int *client_sock_addr = (int*) client_sock_addr; 
    int client_sock = *client_sock_addr; 

    // Before exiting the thread 
    free(client_sock_addr); 
} 
+0

int client_sock = -1; 我不知道爲什麼,但是當我把&client_sock而不是client_sock,整個套接字停止工作。有任何想法嗎? – Tech163 2010-08-15 00:54:22

+2

此更改引入了一個新問題。沒有任何東西可以確保指針和指向的數據在線程完成之前保持有效。解決這個問題的一些方法是:malloc參數塊,並將它釋放到線程中,讓線程信號表明它是通過參數完成的,並在使其失效之前等待該參數。 – jilles 2010-08-15 00:56:58

+2

通常最好是用'pthread_t'對象將參數分組到'struct'中的線程。當你加入這個線程時,你可以拋棄'struct'或重用它或其他任何東西。 – Potatoswatter 2010-08-15 01:00:09

0

這僅僅是因爲你不尊重pthread_create簽名:

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

正如你所看到的第三個參數應該是一個函數指針,所以正確的演員將是(void *(*)(void*))client_sock這將是參數start_routine你必須採取這樣的地址&client_sock