开发者

Thread-specific data

开发者 https://www.devze.com 2023-04-04 13:15 出处:网络
I have a client program as follows and I need to make it multithreaded i.e one thre开发者_如何学Pythonad per connection. But the variable sockfd is to be kept global to one thread. I understand to do

I have a client program as follows and I need to make it multithreaded i.e one thre开发者_如何学Pythonad per connection. But the variable sockfd is to be kept global to one thread. I understand to do this I need to use pthread_key_t, pthread_key_create...etc. But, I am confused how to use it. I would be gratefull for any help.

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;
}

I have executed the program for one thread and works fine. But as I increase the number of threads to more then one ofcourse it does not work because of the global vaiable sockfd. This is a test program for something much larger.

Thanks and Regards


It is very easy to use. You call pthread_key_create(&key_to_sockfd, NULL) at the start of your program then in each thread you will see an initial value of NULL. Use the function pthread_setspecific(key_to_sockfd, <pointer to a struct which contains sockfd>) in each thread.

From then on each thread will see a different pointer to the structure that contains your sockfd. When your thread is done with it, you delete the structure and use pthread_setspecific(key_to_sockfd, NULL)

When the threads are finished you call pthread_key_delete(key_to_sockfd) to remove the storage. You can also automatically cleanup by providing a callback function to pthread_key_create to free up the memory when the thread has finished.


From what I see you don't need a global variable to achieve what you want to do. Create a "state" data structure and initialize it for each thread before launching it. The void* parameter in the thread interface is made for this.


If I look to your code you overwrite with each thread you start the socket descriptor sockfd. So each thread will make a new connection and gets a new sockfd. With this code you have the good possibility one thread is closing the connection of another thread. If you want to use for each thread its own socket descriptor why don't you use a pointer to share the same socket descriptor within the same thread?

void client_thrd(char *argv[])
{
  int sockfd;
  set_connection(&sockfd, argv);
  send_message(&sockfd);
  disconnect(&sockfd);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号