linux c多线程与消息队列实现字符串转化

来源:互联网 发布:热力学计算软件 小木虫 编辑:程序博客网 时间:2024/06/05 00:17

编写一个具有3个子线程的程序,Thread 1从标准输入设备获取一个字符串,并将该字符串发送到消息队列;Thread 2 从消息队列获取该字符串,并将其反转,然后重新发送到消息队列;Thread 3读取Thread 2 发送的消息字符串,并将字符串中的大写字符变为小写,小写字符变为大写;将最终字符串最为结束状态,返回到主线程。主线程显示Thread 3的退出状态。

 #include<stdio.h>      #include<pthread.h>      #include<stdlib.h>      #include<unistd.h>      #include<signal.h>       #include <string.h>      #include <errno.h>      #include <sys/msg.h>     #include <ctype.h>     #define MAX_TEXT 512     struct msg_st      {          long int msg_type;          char text[BUFSIZ];      };     static void thread_one(char* msg);      static void thread_two(char* msg);      static void thread_three(char* msg);     int  main(int argc, char** argv)      {          pthread_t th_one,th_two,th_three;          char * msg="thread";          printf("thread_one starting/\n");          if(pthread_create(&th_one,NULL,(void*)&thread_one,msg)!=0)         {              exit(EXIT_FAILURE);          }          sleep(3);         printf("thread_two starting/\n");           if(pthread_create(&th_two,NULL,(void*)&thread_two,msg)!=0)           {              exit(EXIT_FAILURE);          }    sleep(3);    printf("thread_three starting/\n");          if(pthread_create(&th_three,NULL,(void*)&thread_three,msg)!=0)               exit(EXIT_FAILURE);     pthread_join(th_one,NULL);    pthread_join(th_two,NULL);    pthread_join(th_three,NULL);    sleep(3);        printf("Main thread will sleep 1 S\n");          return 0;      }      static void thread_two(char* msg)      {           int running = 1;       int msgid = -1;       struct msg_st data;       long int msgtype = 0; //注意1       char a[20]={0},*p1,*p2;     //建立消息队列       msgid = msgget((key_t)1234, 0666 | IPC_CREAT);       if(msgid == -1)       {          fprintf(stderr, "msgget failed with error: %d\n", errno);          exit(EXIT_FAILURE);       }          //从队列中获取消息,直到遇到end消息为止          while(running){          if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)          {              fprintf(stderr, "msgrcv failed with errno: %d\n", errno);              exit(EXIT_FAILURE);          }          printf("You wrote: %s\n",data.text);          //遇到end结束          if(strncmp(data.text, "end", 3) == 0)               break;         p1 = data.text;          p2 = a + strlen(data.text) - 1;          for( ; *p1 != '\0'; p1++, p2--)              *p2 = *p1;          *p2='\0';          printf("after reverse string a is: %s\n", a);        //向队列发送数据          data.msg_type = 1;           strcpy(data.text, a);        msgid = msgget((key_t)512, 0666 | IPC_CREAT);              if(msgid == -1)              {              fprintf(stderr, "msgget failed with error: %d\n", errno);              exit(EXIT_FAILURE);              }           if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)          {              fprintf(stderr, "msgsnd failed\n");              exit(EXIT_FAILURE);          }         msgid=msgget((key_t)1234, 0666 | IPC_CREAT);         }          //删除消息队列          if(msgctl(msgid, IPC_RMID, 0) == -1)          {          fprintf(stderr, "msgctl(IPC_RMID) failed\n");          exit(EXIT_FAILURE);          }          exit(EXIT_SUCCESS);      }      static void thread_one(char* msg)      {              int running = 1;          struct msg_st data;          char buffer[BUFSIZ];          int msgid = -1;          //建立消息队列          msgid = msgget((key_t)1234, 0666 | IPC_CREAT);          if(msgid == -1)          {          fprintf(stderr, "msgget failed with error: %d\n", errno);          exit(EXIT_FAILURE);          }          //向消息队列中写消息,直到写入end          while(running)          {          //输入数据          printf("Enter some text: ");          fgets(buffer, BUFSIZ, stdin);          data.msg_type = 1;             strcpy(data.text, buffer);          //向队列发送数据          if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)          {              fprintf(stderr, "msgsnd failed\n");              exit(EXIT_FAILURE);          }          //输入end结束输入          if(strncmp(buffer, "end", 3) == 0)              running = 0;          sleep(1);          }          exit(EXIT_SUCCESS);      } static void thread_three(char* msg)      {           int running = 1,i=0;       int msgid = -1;       struct msg_st data;       long int msgtype = 0;      char a[20]={0};     //建立消息队列       msgid = msgget((key_t)512, 0666 | IPC_CREAT);       if(msgid == -1)      {          fprintf(stderr, "msgget failed with error: %d\n", errno);          exit(EXIT_FAILURE);       }          //从队列中获取消息,直到遇到end消息为止          while(running)          {          if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)          {              fprintf(stderr, "msgrcv failed with errno: %d\n", errno);              exit(EXIT_FAILURE);          }          printf("You reverse result: %s\n",data.text);          //遇到end结束          if(strncmp(data.text, "end", 3) == 0)                  running = 0;          strcpy(a,data.text);        for(i=0;i<strlen(a);i++){          if(a[i]>='a'&&a[i]<='z'){            a[i]=toupper(a[i]);          }else if(a[i]>='A'&&a[i]<='Z'){            a[i]=tolower(a[i]);          }        }            printf("after upper string a is: %s\n", a);        //向队列发送数据          data.msg_type = 1;            strcpy(data.text, a);         msgid = msgget((key_t)1234, 0666 | IPC_CREAT);        if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)          {              fprintf(stderr, "msgsnd failed\n");              exit(EXIT_FAILURE);          }          }          //删除消息队列          if(msgctl(msgid, IPC_RMID, 0) == -1)          {          fprintf(stderr, "msgctl(IPC_RMID) failed\n");          exit(EXIT_FAILURE);          }          exit(EXIT_SUCCESS);      }