[英]Thread-specific data
我有一個客戶端程序,如下所示,我需要使其成為多線程,即每個連接一個線程。 但是變量sockfd將被全局保留在一個線程中。 我知道要執行此操作,我需要使用pthread_key_t,pthread_key_create ...等。 但是,我很困惑如何使用它。 我將不勝感激。
int sockfd;
pthread_key_t key_to_sockfd;
void error(const char *msg)
{
perror(msg);
exit(0);
}
void set_connection(char *argv[])
{
int portno;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
return;
}
void send_message()
{
char buffer[256];
int i=0,n;
do{
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
i++;
}while(i<3);
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
return;
}
void disconnect()
{
close(sockfd);
return;
}
void client_thrd(char *argv[])
{
set_connection(argv);
send_message();
disconnect();
}
int main(int argc, char *argv[])
{
pthread_t thid[2];
int i;
void *status;
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
for(i=0;i<1;i++)
pthread_create(&thid[i],NULL,(void*)&client_thrd,(void*)argv);
for(i=0;i<1;i++)
pthread_join(thid[i],&status);
return 0;
}
我已經為一個線程執行了該程序,並且工作正常。 但是隨着線程數增加到一個以上,由於全局的sockfd,它不起作用。 這是一個更大的測試程序。
謝謝並恭祝安康
這是非常容易使用。 您在程序開始時調用pthread_key_create(&key_to_sockfd, NULL)
,然后在每個線程中將看到NULL的初始值。 在每個線程中使用函數pthread_setspecific(key_to_sockfd, <pointer to a struct which contains sockfd>)
。
從那時起,每個線程將看到一個指向包含sockfd的結構的不同指針。 完成線程處理后,刪除結構並使用pthread_setspecific(key_to_sockfd, NULL)
線程完成后,請調用pthread_key_delete(key_to_sockfd)
刪除存儲。 您還可以通過向pthread_key_create
提供回調函數來自動清理,以在線程完成后釋放內存。
從我的角度來看,您不需要全局變量即可實現您想要的工作。 創建一個“狀態”數據結構,並在啟動每個線程之前對其進行初始化。 為此在線程接口中設置了void*
參數。
如果我查看您的代碼,則用每個線程覆蓋,則啟動套接字描述符sockfd。 因此,每個線程將建立一個新的連接並獲得一個新的sockfd。 使用此代碼,您很可能一個線程正在關閉另一個線程的連接。 如果要為每個線程使用自己的套接字描述符,為什么不使用指針在同一線程內共享同一套接字描述符?
void client_thrd(char *argv[])
{
int sockfd;
set_connection(&sockfd, argv);
send_message(&sockfd);
disconnect(&sockfd);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.