多线程开发
文章目錄
- 1 多線程開發
1 多線程開發
先看幾個基本概念:
線程ID:
//頭文件 #include<pthread.h> pthread_t ;typedef unsigned long int pthread_t;線程屬性:
pthread_attr_t ; int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);創建線程:
int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, (void*)(*start_rtn)(void*), void *arg);//pthread_t *tidp 線程ID //const pthread_attr_t *attr 線程屬性 //(void*)(*start_rtn)(void*) 函數指針,處理函數 //void *arg 處理函數的參數TCP多線程:
服務端示例代碼:
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h>#include <netinet/in.h> //#include <Windows.h> #include <pthread.h> #include <malloc.h> #include <string.h>#include <sys/stat.h> #include <fcntl.h> #include <unistd.h>#include <netdb.h>#include <sys/time.h>#include <signal.h>#define SERVER_PORT_TCP 6666 #define TCP_BACKLOG 10/* 在sock_fd 進行監聽,在 new_fd 接收新的鏈接 */ int sock_fd, new_fd;void printf_hex(char *buf, int len) {int i;for(i = 0; i < len; i++){printf("0x%x ", buf[i]);}}void sig_chld(int signo) {pid_t pid;int stat;while((pid = waitpid(-1, &stat, WNOHANG)) > 0)printf("child %d terminated\r\n", pid);return; }void *__tcp_server(void *pdata) {int new_socket = pdata;//處理目標ssize_t ret;char recvbuf[512];char *buf = "hello! I'm server!";while(1){if((ret = recv(new_socket, recvbuf, sizeof(recvbuf), 0)) == -1){printf("recv error \r\n");return -1;}printf("recv :\r\n");printf("%s", recvbuf);printf("\r\n");sleep(2);if((ret = send(new_socket, buf, strlen(buf) + 1, 0)) == -1){perror("send : ");}}close(new_socket); }int main(void) {char command[1024];char *str;/* 自己的地址信息 */struct sockaddr_in my_addr;/* 連接者的地址信息*/struct sockaddr_in their_addr;int sin_size;struct sockaddr_in *cli_addr;/* 1 、創建socket */if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("socket is error\r\n");exit(1);}/* 主機字節順序 *//* 協議 */my_addr.sin_family = AF_INET;my_addr.sin_port = htons(6666);/* 當前IP 地址寫入 */my_addr.sin_addr.s_addr = INADDR_ANY;/* 將結構體其余的都清零 */bzero(&(my_addr.sin_zero), 8);/* bind 綁定*/if(bind(sock_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1){perror("bind is error\r\n");exit(1);}/* 開始監聽 */if(listen(sock_fd, TCP_BACKLOG) == -1){perror("listen is error\r\n");exit(1);}printf("start accept\n");/* 因為我們后面會創建出許多子進程來服務新的鏈接一旦子進程異常終止了,需要父進程來進行資源回收*/signal(SIGCHLD, sig_chld); //在這里處理僵死進程/* accept() 循環 */while(1){sin_size = sizeof(struct sockaddr_in);if((new_fd = accept(sock_fd, (struct sockaddr *)&their_addr, (socklen_t *)&sin_size)) == -1){perror("accept");continue;}pthread_t server_thread;pthread_attr_t server_thread_attr;/* 創建子進程 */pthread_attr_init(&server_thread_attr); //初始化進程屬性pthread_attr_setdetachstate(&server_thread_attr, PTHREAD_CREATE_DETACHED);// if (pthread_create(&recv_thread, &recv_thread_attr, recv_pthread, NULL) < 0)if (pthread_create(&server_thread, &server_thread_attr, __tcp_server, new_fd) < 0){perror("pthread_create");}}return 0; }客戶端示例代碼:
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> //#include <Windows.h> #include <pthread.h> #include <malloc.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h>#include <netdb.h>#include <sys/time.h>#include <signal.h>int sockfd;//#define SERVER_IP "106.13.62.194" #define SERVER_IP "127.0.0.1"#define SERVER_PORT 6666void printf_hex(char *buf, int len) {int i;for(i = 0; i < len; i++){printf("0x%x ", buf[i]);}}char *device_id ;int main(int argc,char **argv) {char command[1024];char *str;/* 連接者的主機信息 */struct sockaddr_in their_addr; if(argc != 2){printf("pls input devide id\r\n");return 0;}device_id = (argv[1]);if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){/* 如果socket()調用出現錯誤則顯示錯誤信息并退出 */perror("socket"); // exit(1);}/* 主機字節順序 */their_addr.sin_family = AF_INET;/* 網絡字節順序,短整型 */their_addr.sin_port = htons(SERVER_PORT);their_addr.sin_addr.s_addr = inet_addr(SERVER_IP);/* 將結構剩下的部分清零*/bzero(&(their_addr.sin_zero), 8);if(connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1){/* 如果connect()建立連接錯誤,則顯示出錯誤信息,退出 */perror("connect");exit(1);}ssize_t ret;char recvbuf[512];char buf[1024];sprintf(buf, "hello, I'm %s", device_id);while(1){if((ret = send(sockfd, buf, strlen(buf) + 1, 0)) == -1){perror("send : ");}sleep(2);if((ret = recv(sockfd, &recvbuf, sizeof(recvbuf), 0)) == -1){return -1;}printf("recv :\r\n");printf("%s", recvbuf);printf("\r\n");sleep(2);}close(sockfd);return 0; }參考資料:
總結
- 上一篇: 西麦食品是中外合资企业吗
- 下一篇: Shell中的常用操作