为了账号安全,请及时绑定邮箱和手机立即绑定

作业社区

探索学习新天地,共享知识资源!

0 提交作业
0 布置作业
0 满分作业
得分 100
学习任务

胡汉三66 的学生作业:

client.c #include #include #include #include // bzore() #include // close() #include #include #include #include // TCP客户端连接 // ./a.out ip port int main(int argc, const char *argv[]) { int sfd,ret; ssize_t sbytes = 0; char buffer[1024] = "Hello,server"; char *pbuffer = NULL; int length = 0; struct sockaddr_in svr_addr; if(argc != 3){ fprintf(stderr,"Usage : %s < ip > < port >.\n",argv[0]); exit(EXIT_FAILURE); } // 1.创建套接字 sfd = socket(AF_INET,SOCK_STREAM,0); if(sfd == -1){ perror("[ERROR] Failed to socket."); exit(EXIT_FAILURE); } // 2.建立连接 bzero(&svr_addr,sizeof(struct sockaddr_in)); // 指针指向空间初始化(清零) svr_addr.sin_family = AF_INET; // 协议族 svr_addr.sin_port = htons(atoi(argv[2])); // 端口 svr_addr.sin_addr.s_addr = inet_addr(argv[1]); // IP ret = connect(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); // 客户端 连接 服务器 if(ret == -1){ perror("[ERROR] Failed to connect."); exit(EXIT_FAILURE); } for(;;){ // 循环输入发送 length = strlen(buffer); pbuffer = (char *)malloc(length + 4); memcpy(pbuffer,&length,4); // 存储字节数 memcpy(pbuffer + 4,buffer,length); // 存储数据内容 sbytes = send(sfd,pbuffer,length + 4,0); if(sbytes == -1){ perror("[ERROR] Failed to send."); exit(EXIT_FAILURE); } usleep(100); // 休息100微妙 // 100微妙 = 0.0001秒 } close(sfd); // 关闭 文件描述符 return 0; } server.c #include #include #include #include // bzore() #include // close() #include #include #include #include #define BACKLOG 10 // 监听队列最大值 // TCP服务器连接 // ./a.out ip port int main(int argc, const char *argv[]) { int sfd,ret,cfd; struct sockaddr_in svr_addr,cli_addr; ssize_t rbytes = 0,sbytes = 0; char buffer[1024] = {0}; int length; int total_received; // 统计当前接收的总字节数 socklen_t len = sizeof(struct sockaddr_in); if(argc != 3){ fprintf(stderr,"Usage : %s < ip > < port >.\n",argv[0]); exit(EXIT_FAILURE); } // 1.创建套接字 sfd = socket(AF_INET,SOCK_STREAM,0); if(sfd == -1){ perror("[ERROR] Failed to socket."); exit(EXIT_FAILURE); } printf("sfd = %d\n",sfd); bzero(&svr_addr,sizeof(struct sockaddr_in)); // 指针指向空间初始化(清零) svr_addr.sin_family = AF_INET; // 协议族 svr_addr.sin_port = htons(atoi(argv[2])); // 端口 svr_addr.sin_addr.s_addr = inet_addr(argv[1]); // IP // 2.绑定ip地址与端口号 ret = bind(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); if(ret == -1){ perror("[ERROR] Failed to bind."); exit(EXIT_FAILURE); } // 3.建立监听队列 ret = listen(sfd,BACKLOG); if(ret == -1){ perror("[ERROR] Failed to listen."); exit(EXIT_FAILURE); } // 4.建立连接,并产生新的客户端用于数据收发 cfd = accept(sfd,(struct sockaddr *)&cli_addr,&len); if(cfd == -1){ perror("[ERROR] Failed to accept."); exit(EXIT_FAILURE); } printf("ip : %s port : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port)); for(;;){ length = 0; int total_received = 0; // 统计当前接收的总字节数 rbytes = recv(cfd,&length,4,0); if(rbytes == -1){ perror("[ERROR] Failed to recv."); exit(EXIT_FAILURE); } for(;;){ rbytes = recv(cfd,buffer + total_received,length - total_received,0); if(rbytes == -1){ perror("[ERROR] Failed to recv."); exit(EXIT_FAILURE); }else if(rbytes > 0){ // 如果收到数据 total_received += rbytes; if(total_received == length) break; }else if(rbytes == 0){ printf("The client has been shutdown.\n"); break; } } printf("buffer : %s\n",buffer); sleep(1); // 休息1秒 } close(sfd); // 关闭 文件描述符 close(cfd); return 0; } 【图片】

得分 100
学习任务

浪潮君 的学生作业:

#include #include #include #include #include // 定义一个结构体,封装两个命名信号量的指针,便于统一管理和传递 typedef struct { sem_t *sem_zero; // 信号量1,初始值为 0,常用于“等待条件满足” sem_t *sem_one; // 信号量2,初始值为 1,常用于“互斥访问”或资源令牌 } SemaphoreSet; int main() { SemaphoreSet semaphores; // 声明信号量集合结构体变量 // 使用 sem_open 创建命名信号量: // 参数含义: // - 名字以 / 开头(是 POSIX 命名要求) // - O_CREAT | O_EXCL 表示“如果已存在则报错” // - 0644 是文件权限 // - 最后一个参数是初始值 semaphores.sem_zero = sem_open("/sem_zero", O_CREAT | O_EXCL, 0644, 0); // 初始为 0 semaphores.sem_one = sem_open("/sem_one", O_CREAT | O_EXCL, 0644, 1); // 初始为 1 // 错误检查:如果 sem_zero 创建失败,立即退出 if (semaphores.sem_zero == SEM_FAILED) { perror("sem_open sem_zero failed"); exit(EXIT_FAILURE); } // 错误检查:如果 sem_one 创建失败,释放 sem_zero 并退出(回滚清理) if (semaphores.sem_one == SEM_FAILED) { perror("sem_open sem_one failed"); sem_close(semaphores.sem_zero); // 关闭 sem_zero 引用 sem_unlink("/sem_zero"); // 删除系统中的 sem_zero 信号量 exit(EXIT_FAILURE); } // 如果两个信号量都成功创建,打印提示信息 printf("命名信号量集合已初始化:/sem_zero = 0, /sem_one = 1\n"); // 关闭两个信号量的引用(释放当前进程持有的句柄) sem_close(semaphores.sem_zero); sem_close(semaphores.sem_one); // 删除命名信号量,释放系统内核资源 sem_unlink("/sem_zero"); sem_unlink("/sem_one"); return 0; }

得分 100
学习任务

胡汉三66 的学生作业:

1.粘包原因:底层逻辑:TCP协议子啊底层是字节流,并不关注应用层的消息边界。具体分两类发送方和接收方. 1-1. 发送方一: 发送多个较小数据包,一般是小于内核缓冲区大小。默认情况下,tcp采用Nagle算法,会合并连续的小数据包一次性发送,形成粘包。 1-2. 发送方二: 发送一个大数据包,大数据包大于MTU(最大输出单元),会发生拆包,将字节流进行切片分成多个包进行发送,拆分后的大数据包形成粘包。 2. 接收方: 客户端发送的速度大于服务器接收的速度,在缓冲区缓存了多个数据包,服务器一次性读取,则会读取多个数据包,也就是粘包。 client.c #include #include #include #include // bzore() #include // close() #include #include #include #include // TCP客户端连接 // ./a.out ip port int main(int argc, const char *argv[]) { int sfd,ret; ssize_t sbytes = 0, rbytes = 0; char buffer[1024] = {0}; struct sockaddr_in svr_addr; if(argc != 3){ fprintf(stderr,"Usage : %s < ip > < port >.\n",argv[0]); exit(EXIT_FAILURE); } // 1.创建套接字 sfd = socket(AF_INET,SOCK_STREAM,0); if(sfd == -1){ perror("[ERROR] Failed to socket."); exit(EXIT_FAILURE); } // 2.建立连接 bzero(&svr_addr,sizeof(struct sockaddr_in)); // 指针指向空间初始化(清零) svr_addr.sin_family = AF_INET; // 协议族 svr_addr.sin_port = htons(atoi(argv[2])); // 端口 svr_addr.sin_addr.s_addr = inet_addr(argv[1]); // IP ret = connect(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); // 客户端 连接 服务器 if(ret == -1){ perror("[ERROR] Failed to connect."); exit(EXIT_FAILURE); } for(;;){ // 循环输入发送 // 获取数据 strcpy(buffer,"Hello,server"); // 3.发送数据 (客户端-->服务器) sbytes = send(sfd,buffer,strlen(buffer),0); // "+1" ---> "\0" if(sbytes == -1){ perror("[ERROR] Failed to send."); exit(EXIT_FAILURE); } usleep(100); // 休息100微妙 // 100微妙 = 0.0001秒 } close(sfd); // 关闭 文件描述符 return 0; } server.c #include #include #include #include // bzore() #include // close() #include #include #include #include #define BACKLOG 10 // 监听队列最大值 // TCP服务器连接 // ./a.out ip port int main(int argc, const char *argv[]) { int sfd,ret,cfd; struct sockaddr_in svr_addr,cli_addr; ssize_t rbytes = 0,sbytes = 0; char buffer[1024] = {0}; socklen_t len = sizeof(struct sockaddr_in); if(argc != 3){ fprintf(stderr,"Usage : %s < ip > < port >.\n",argv[0]); exit(EXIT_FAILURE); } // 1.创建套接字 sfd = socket(AF_INET,SOCK_STREAM,0); if(sfd == -1){ perror("[ERROR] Failed to socket."); exit(EXIT_FAILURE); } printf("sfd = %d\n",sfd); bzero(&svr_addr,sizeof(struct sockaddr_in)); // 指针指向空间初始化(清零) svr_addr.sin_family = AF_INET; // 协议族 svr_addr.sin_port = htons(atoi(argv[2])); // 端口 svr_addr.sin_addr.s_addr = inet_addr(argv[1]); // IP // 2.绑定ip地址与端口号 ret = bind(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); if(ret == -1){ perror("[ERROR] Failed to bind."); exit(EXIT_FAILURE); } // 3.建立监听队列 ret = listen(sfd,BACKLOG); if(ret == -1){ perror("[ERROR] Failed to listen."); exit(EXIT_FAILURE); } // 4.建立连接,并产生新的客户端用于数据收发 cfd = accept(sfd,(struct sockaddr *)&cli_addr,&len); if(cfd == -1){ perror("[ERROR] Failed to accept."); exit(EXIT_FAILURE); } printf("ip : %s port : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port)); for(;;){ memset(buffer,0,sizeof(buffer)); // 清空 rbytes = recv(cfd,buffer,sizeof(buffer),0); if(rbytes == -1){ perror("[ERROR] Failed to recv."); exit(EXIT_FAILURE); }else if(rbytes > 0){ // 如果收到数据 printf("buffer : %s\n",buffer); }else if(rbytes == 0){ printf("The client has been shutdown.\n"); break; } sleep(1); // 休息1秒 } close(sfd); // 关闭 文件描述符 close(cfd); return 0; } 【图片】

得分 100
学习任务

浪潮君 的学生作业:

int main(int argc, char *argv[]) { // 参数检查:至少需要输入生产者数量、消费者数量,以及每个生产者的产品数量 if (argc < 3) { fprintf(stderr, "用法: %s ... \n", argv[0]); exit(EXIT_FAILURE); } // 解析命令行参数中的生产者数量和消费者数量 int producer_num = atoi(argv[1]); int consumer_num = atoi(argv[2]); // 边界检查,防止生产者或消费者数量超出预设最大值范围 if (producer_num MAX_PRODUCERS || consumer_num MAX_CONSUMERS) { fprintf(stderr, "生产者或消费者数量超出范围(最大%d/%d)\n", MAX_PRODUCERS, MAX_CONSUMERS); exit(EXIT_FAILURE); } // 检查参数数量是否正确,为每个生产者都指定了生产数量 if (argc != 3 + producer_num) { fprintf(stderr, "请为每个生产者指定生产数量\n"); exit(EXIT_FAILURE); } // 定义数组,用于保存生产者和消费者线程ID pthread_t producer_tids[producer_num]; pthread_t consumer_tids[consumer_num]; int total_produce = 0; // 统计所有生产者生产的产品总数 // 创建生产者线程 for (int i = 0; i < producer_num; i++) { // 为当前生产者分配参数结构体内存 ProducerArg *parg = malloc(sizeof(ProducerArg)); parg->produce_count = atoi(argv[3 + i]); // 解析生产数量 parg->id = i + 1; // 生产者编号从1开始 total_produce += parg->produce_count; // 累加总生产数量 // 创建生产者线程,传入参数结构体 if (pthread_create(&producer_tids[i], NULL, producer_thread, parg) != 0) { perror("pthread_create producer"); exit(EXIT_FAILURE); } } // 创建消费者线程 for (int i = 0; i < consumer_num; i++) { // 为当前消费者分配参数结构体内存 ConsumerArg *carg = malloc(sizeof(ConsumerArg)); carg->id = i + 1; // 消费者编号从1开始 // 创建消费者线程,传入参数结构体 if (pthread_create(&consumer_tids[i], NULL, consumer_thread, carg) != 0) { perror("pthread_create consumer"); exit(EXIT_FAILURE); } } // 等待所有生产者线程结束,确保所有产品已生产完毕 for (int i = 0; i < producer_num; i++) { pthread_join(producer_tids[i], NULL); } // 通知消费者所有生产者已完成生产 pthread_mutex_lock(&mtx); all_producers_done = true; pthread_cond_broadcast(&cond); // 唤醒所有可能正在等待的消费者线程 pthread_mutex_unlock(&mtx); // 等待所有消费者线程结束,确保所有产品已被消费 for (int i = 0; i < consumer_num; i++) { pthread_join(consumer_tids[i], NULL); } // 销毁互斥锁和条件变量,释放系统资源 pthread_mutex_destroy(&mtx); pthread_cond_destroy(&cond); // 程序结束提示 printf("所有产品已生产和消费完毕。\n"); return 0; }

得分 100
学习任务

浪潮君 的学生作业:

#include #include #include #include #include // 共享资源:产品数量 static int number = 0; // 互斥锁,用于保护临界区 pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; // 条件变量,用于线程间的同步(通知消费者有产品了) pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // 生产者线程参数结构体 typedef struct { int cnt; // 当前线程需要生产的产品数量 int producer_id; // 生产者编号,用于打印 } ProducerArg; // 生产者线程执行函数 void *thread_handler(void *arg) { ProducerArg *parg = (ProducerArg *) arg; int cnt = parg->cnt; int id = parg->producer_id; for (int i = 0; i < cnt; i++) { pthread_mutex_lock(&mtx); // 进入临界区 ++number; // 模拟生产一个产品 printf("线程 [%d] 生产一个产品,当前产品总数: %d\n", id, number); pthread_cond_signal(&cond); // 通知消费者线程有新产品 pthread_mutex_unlock(&mtx); // 退出临界区 usleep(rand() % 500000); // 模拟生产所需的耗时 } free(parg); // 释放参数结构体,防止内存泄漏 pthread_exit(NULL); // 正常退出线程 } int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "用法: %s ...\n", argv[0]); exit(EXIT_FAILURE); } int num_producers = argc - 1; // 生产者线程数量 pthread_t tids[num_producers]; // 保存所有线程的 ID int total_of_produce = 0; // 记录总共需要生产的产品数量 int total_of_consume = 0; // 记录已消费的产品数量 // 创建所有生产者线程 for (int i = 0; i < num_producers; i++) { int count = atoi(argv[i + 1]); // 当前生产者要生产的产品数量 total_of_produce += count; // 累加到总生产数量 // 为每个线程分配参数结构体 ProducerArg *parg = malloc(sizeof(ProducerArg)); if (!parg) { perror("malloc"); exit(EXIT_FAILURE); } parg->cnt = count; parg->producer_id = i + 1; // 创建线程 if (pthread_create(&tids[i], NULL, thread_handler, parg) != 0) { perror("pthread_create"); free(parg); exit(EXIT_FAILURE); } } // 主线程作为消费者 while (total_of_consume < total_of_produce) { pthread_mutex_lock(&mtx); // 加锁进入临界区 // 如果当前没有产品,则等待条件变量 while (number == 0) { pthread_cond_wait(&cond, &mtx); // 自动释放锁并挂起,收到 signal 后会自动加锁恢复 } // 有产品可消费 --number; ++total_of_consume; printf("主线程消费一个产品,剩余产品数: %d\n", number); pthread_mutex_unlock(&mtx); // 解锁退出临界区 sleep(1); // 模拟消费耗时 } // 等待所有生产者线程退出 for (int i = 0; i < num_producers; i++) { pthread_join(tids[i], NULL); } // 清理资源 pthread_mutex_destroy(&mtx); pthread_cond_destroy(&cond); printf("所有产品已被消费完毕,总共消费 %d 个产品。\n", total_of_consume); return 0; }

得分 100
学习任务

胡汉三66 的学生作业:

tcp_client.c #include #include #include #include // bzore() #include // close() #include #include #include #include // TCP客户端连接 // ./a.out ip port int main(int argc, const char *argv[]) { int sfd,ret; ssize_t sbytes = 0, rbytes = 0; char buffer[1024] = {0}; struct sockaddr_in svr_addr; if(argc != 3){ fprintf(stderr,"Usage : %s < ip > < port >.\n",argv[0]); exit(EXIT_FAILURE); } // 1.创建套接字 sfd = socket(AF_INET,SOCK_STREAM,0); if(sfd == -1){ perror("[ERROR] Failed to socket."); exit(EXIT_FAILURE); } printf("sfd = %d\n",sfd); // 2.建立连接 bzero(&svr_addr,sizeof(struct sockaddr_in)); // 指针指向空间初始化(清零) svr_addr.sin_family = AF_INET; // 协议族 svr_addr.sin_port = htons(atoi(argv[2])); // 端口 svr_addr.sin_addr.s_addr = inet_addr(argv[1]); // IP ret = connect(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); // 客户端 连接 服务器 if(ret == -1){ perror("[ERROR] Failed to connect."); exit(EXIT_FAILURE); } for(;;){ // 循环输入发送 // 输入数据 putchar('>'); memset(buffer,0,sizeof(buffer)); fgets(buffer,sizeof(buffer),stdin); // 3.发送数据 (客户端-->服务器) sbytes = send(sfd,buffer,strlen(buffer) + 1,0); // "+1" ---> "\0" if(ret == -1){ perror("[ERROR] Failed to send."); exit(EXIT_FAILURE); } if(strncmp(buffer,"quit",4) == 0) break; // 4.接收数据 (服务器--->客户端) bzero(buffer,sizeof(buffer)); // 指针指向空间初始化(清零) rbytes = recv(sfd,buffer,sizeof(buffer),0); // "+1" ---> "\0" if(ret == -1){ perror("[ERROR] Failed to recv."); exit(EXIT_FAILURE); }else if(rbytes > 0){ printf("buffer : %s\n",buffer); }else if(rbytes == 0){ printf("The server has been shut down.\n"); } } close(sfd); // 关闭 文件描述符 return 0; } tcp_server.c #include #include #include #include // bzore() #include // close() #include #include #include #include #define BACKLOG 10 // 监听队列最大值 // TCP服务器连接 // ./a.out ip port int main(int argc, const char *argv[]) { int sfd,ret,cfd; struct sockaddr_in svr_addr,cli_addr; ssize_t rbytes = 0,sbytes = 0; char buffer[1024] = {0}; socklen_t len = sizeof(struct sockaddr_in); if(argc != 3){ fprintf(stderr,"Usage : %s < ip > < port >.\n",argv[0]); exit(EXIT_FAILURE); } // 1.创建套接字 sfd = socket(AF_INET,SOCK_STREAM,0); if(sfd == -1){ perror("[ERROR] Failed to socket."); exit(EXIT_FAILURE); } printf("sfd = %d\n",sfd); bzero(&svr_addr,sizeof(struct sockaddr_in)); // 指针指向空间初始化(清零) svr_addr.sin_family = AF_INET; // 协议族 svr_addr.sin_port = htons(atoi(argv[2])); // 端口 svr_addr.sin_addr.s_addr = inet_addr(argv[1]); // IP // 2.绑定ip地址与端口号 ret = bind(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); if(ret == -1){ perror("[ERROR] Failed to bind."); exit(EXIT_FAILURE); } // 3.建立监听队列 ret = listen(sfd,BACKLOG); if(ret == -1){ perror("[ERROR] Failed to listen."); exit(EXIT_FAILURE); } // 4.建立连接,并产生新的客户端用于数据收发 cfd = accept(sfd,(struct sockaddr *)&cli_addr,&len); if(cfd == -1){ perror("[ERROR] Failed to accept."); exit(EXIT_FAILURE); } printf("ip : %s port : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port)); for(;;){ memset(buffer,0,sizeof(buffer)); // 清空 rbytes = recv(cfd,buffer,sizeof(buffer),0); if(rbytes == -1){ perror("[ERROR] Failed to recv."); exit(EXIT_FAILURE); }else if(rbytes > 0){ // 如果收到数据 // 如果输入是"quit",则退出 if(strncmp(buffer,"quit",4) == 0) break; // 将接收到的 客户端数据 回传给 客户端 sbytes = send(cfd,buffer,sizeof(buffer),0); if(sbytes == -1){ perror("[ERROR] Failed to recv."); exit(EXIT_FAILURE); } }else if(rbytes == 0){ printf("The client has been shutdown.\n"); break; } } close(sfd); // 关闭 文件描述符 close(cfd); return 0; } 【图片】

得分 100
学习任务

胡汉三66 的学生作业:

#include #include #include #include // bzore() #include // close() #include #include #include #include #define BACKLOG 10 // 监听队列最大值 // TCP服务器连接 // ./a.out ip port int main(int argc, const char *argv[]) { int sfd,ret,cfd; struct sockaddr_in svr_addr,cli_addr; socklen_t len = sizeof(struct sockaddr_in); if(argc != 3){ fprintf(stderr,"Usage : %s < ip > < port >.\n",argv[0]); exit(EXIT_FAILURE); } // 1.创建套接字 sfd = socket(AF_INET,SOCK_STREAM,0); if(sfd == -1){ perror("[ERROR] Failed to socket."); exit(EXIT_FAILURE); } printf("sfd = %d\n",sfd); bzero(&svr_addr,sizeof(struct sockaddr_in)); // 指针指向空间初始化(清零) svr_addr.sin_family = AF_INET; // 协议族 svr_addr.sin_port = htons(atoi(argv[2])); // 端口 svr_addr.sin_addr.s_addr = inet_addr(argv[1]); // IP // 2.绑定ip地址与端口号 ret = bind(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); if(ret == -1){ perror("[ERROR] Failed to bind."); exit(EXIT_FAILURE); } // 3.建立监听队列 ret = listen(sfd,BACKLOG); if(ret == -1){ perror("[ERROR] Failed to listen."); exit(EXIT_FAILURE); } // 4.建立连接,并产生新的客户端用于数据收发 cfd = accept(sfd,(struct sockaddr *)&cli_addr,&len); if(cfd == -1){ perror("[ERROR] Failed to accept."); exit(EXIT_FAILURE); } printf("ip : %s port : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port)); for(;;){ } close(sfd); // 关闭 文件描述符 return 0; } 【图片】

得分 100
学习任务

浪潮君 的学生作业:

#include // 提供 printf、perror 等标准输出函数 #include // 提供 malloc、free、exit 等动态内存和退出控制 #include // 提供 pthread 线程函数 #include // 提供字符串处理函数,如 strcpy // 使用匿名结构体定义类型 person typedef struct { char name[20]; // 名字字段,最多 19 个字符 + '\0' int age; // 年龄字段 } person; // 子线程函数:创建并返回一个 person 结构体指针 void *thread_func(void *) { // 动态分配内存,确保线程退出后数据依然有效 person *p = malloc(sizeof(person)); if (p == NULL) { perror("malloc failed"); // 分配失败,打印错误信息 pthread_exit(NULL); // 线程安全地退出 } // 填写结构体字段 strcpy(p->name, "Tom"); // 设置名字 p->age = 30; // 设置年龄 return (void *) p; // 返回结构体指针(会被 pthread_join 接收) } int main() { pthread_t tid; // 线程 ID person *result = NULL; // 用于接收线程返回的结构体指针 // 创建子线程,执行 thread_func 函数 if (pthread_create(&tid, NULL, thread_func, NULL) != 0) { perror("线程创建失败"); exit(EXIT_FAILURE); // 创建失败,程序退出 } // 主线程等待子线程结束,并接收其返回的结构体地址 if (pthread_join(tid, (void **) &result) != 0) { perror("线程等待失败"); exit(EXIT_FAILURE); } // 如果接收成功,打印结构体中的数据 if (result != NULL) { printf("姓名:%s\n", result->name); printf("年龄:%d\n", result->age); free(result); // 使用完后释放动态内存,防止内存泄漏 } return 0; }

微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号