
作业社区
探索学习新天地,共享知识资源!
浪潮君 的学生作业:
#include #include #include #include // 定义一个结构体 Person,包含名字和年龄 typedef struct { char name[20]; int age; } Person; // 子线程的函数,用于创建并返回一个结构体指针 void *thread_func(void *) { // 动态分配结构体内存(分配到堆上,避免线程栈退出后失效) Person *p = malloc(sizeof(*p)); if (NULL == p) { perror("malloc failed"); pthread_exit(NULL); // 分配失败时,线程安全退出 } // 初始化结构体数据 strcpy(p->name, "Tom"); p->age = 28; // 将结构体指针作为线程返回值传递回主线程 return p; } int main(int argc, char *argv[]) { 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("pthread_join"); exit(EXIT_FAILURE); } // 打印结构体内容(验证子线程传递的数据) if (result != NULL) { printf("姓名:%s\n", result->name); printf("年龄:%d\n", result->age); } // 释放堆内存,防止内存泄漏 free(result); return 0; }





浪潮君 的学生作业:
#include #include #include #include // 线程A的函数 void *thread_A(void *arg) { for (int i = 0; i < 3; i++) { printf("线程A:第 %d 次执行\n", i + 1); sleep(1); // 模拟耗时操作 } pthread_exit(NULL); // 显式退出线程(可省略) } // 线程B的函数 void *thread_B(void *arg) { for (int i = 0; i < 3; i++) { printf("线程B:第 %d 次执行\n", i + 1); sleep(1); // 模拟耗时操作 } pthread_exit(NULL); } int main() { pthread_t tid_A, tid_B; // 声明两个线程ID // 创建线程A if (pthread_create(&tid_A, NULL, thread_A, NULL) != 0) { perror("创建线程A失败"); exit(EXIT_FAILURE); } // 创建线程B if (pthread_create(&tid_B, NULL, thread_B, NULL) != 0) { perror("创建线程B失败"); exit(EXIT_FAILURE); } // 设置线程A、B为分离状态: // 一旦线程执行完,系统自动释放资源,不需要主线程回收 pthread_detach(tid_A); pthread_detach(tid_B); // 因为线程是分离状态,主线程不能使用 join 来等待它们 // 为防止主线程提前退出,我们 sleep 一段时间,确保子线程有时间完成 sleep(5); // 等待足够的时间(3次sleep(1) ≈ 3秒,预留2秒缓冲) printf("主线程结束(不等待子线程)\n"); return 0; }





浪潮君 的学生作业:
#include #include #include #include // 线程A的任务函数 void *thread_A(void *arg) { for (int i = 0; i < 5; i++) { printf("线程A正在运行,第 %d 次\n", i + 1); sleep(1); } return NULL; } // 线程B的任务函数 void *thread_B(void *arg) { for (int i = 0; i < 5; i++) { printf("线程B正在运行,第 %d 次\n", i + 1); sleep(1); } return NULL; } int main() { pthread_t tid_A, tid_B; // 创建线程A if (pthread_create(&tid_A, NULL, thread_A, NULL) != 0) { perror("创建线程A失败"); exit(EXIT_FAILURE); } // 创建线程B if (pthread_create(&tid_B, NULL, thread_B, NULL) != 0) { perror("创建线程B失败"); exit(EXIT_FAILURE); } // 等待两个线程执行结束 pthread_join(tid_A, NULL); pthread_join(tid_B, NULL); printf("主线程结束。\n"); return 0; }





浪潮君 的学生作业:
#include #include #include #include #include #include #include #define LOOP_COUNT 10 // 定义循环次数(输出多少行) #define OUTPUT_FILE "output.txt" // 输出文件名 int main() { int pipefd[2]; // pipefd[0] 是读端,pipefd[1] 是写端。用于父子进程间同步通信 // 创建管道,pipefd[0] 为读端,pipefd[1] 为写端 if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } // 创建子进程 pid_t pid = fork(); if (pid < 0) { perror("fork"); exit(EXIT_FAILURE); } if (pid == 0) { // ---------------------- 子进程逻辑 ---------------------- close(pipefd[1]); // 子进程不写管道,只用读管道,所以关闭写端 // 子进程单独打开输出文件(使用追加模式),防止和父进程共享文件描述符冲突 int fd = open(OUTPUT_FILE, O_WRONLY | O_APPEND); if (fd == -1) { perror("child open"); exit(EXIT_FAILURE); } for (int i = 1; i





浪潮君 的学生作业:
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; }
胡汉三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; } 【图片】





浪潮君 的学生作业:
#include #include #include #include // 定义一个全局变量,两个线程都会对它执行加一操作 static int global = 0; // 声明并初始化互斥锁 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 子线程函数:对 global 执行 loops 次加一操作 void *do_thread(void *arg) { int loops = *(int *)arg; // 从参数中取出循环次数 for (int i = 0; i < loops; i++) { pthread_mutex_lock(&mutex); // 加锁:进入临界区 global++; // 修改共享变量 pthread_mutex_unlock(&mutex); // 解锁:退出临界区 } return NULL; // 线程无返回值 } int main() { pthread_t tid[2]; // 定义两个线程 ID int loops = 1000000; // 每个线程加一百万次,共两百万次 // 创建两个线程,执行 do_thread 函数,传入同一个 loops 参数地址 for (int i = 0; i < 2; i++) { if (pthread_create(&tid[i], NULL, do_thread, &loops) != 0) { perror("pthread_create failed"); // 创建失败则报错并退出 exit(EXIT_FAILURE); } } // 等待两个线程执行完毕(阻塞主线程) pthread_join(tid[0], NULL); pthread_join(tid[1], NULL); // 输出最终的 global 值,应为 2 × 1000000 = 2000000 printf("global = %d\n", global); return 0; }
浪潮君 的学生作业:
#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; }
浪潮君 的学生作业:
#include // 标准输入输出函数,如 printf、fprintf #include // 提供 exit() 和 EXIT_FAILURE 宏 #include // 提供 fork()、sleep() 等系统调用 #include // 提供 wait() 函数,等待子进程 #include // 提供时间函数,如 time()、strftime() #include // 提供文件控制宏(本程序中未使用,可删除) int main() { // 打开日志文件,写入模式,如果文件存在则清空,不存在则创建 FILE *fp = fopen("time_log.txt", "w"); if (fp == NULL) { perror("无法打开文件"); exit(EXIT_FAILURE); // 打开失败则退出程序 } // 循环 10 次,每次创建一个子进程,完成一次完整的时间日志写入 for (int i = 1; i
浪潮君 的学生作业:
#include // 提供 printf() #include // 提供 exit() #include // 提供 POSIX 线程函数 #include // 提供 sleep() // 子线程执行函数 void* thread_func(void *) { // 获取当前线程的 ID pthread_t tid = pthread_self(); // 打印线程 ID(转换为无符号长整型便于输出) printf("子线程(分离)ID: %lu\n", (unsigned long) tid); // 线程结束(返回 NULL) return NULL; } int main() { pthread_t tid1, tid2; // 定义两个线程变量,用于保存线程 ID // 创建第一个线程 if (pthread_create(&tid1, NULL, thread_func, NULL) != 0) { perror("创建线程 1 失败"); exit(EXIT_FAILURE); } // 设置第一个线程为分离状态(不再使用 pthread_join 等待它) pthread_detach(tid1); // 创建第二个线程 if (pthread_create(&tid2, NULL, thread_func, NULL) != 0) { perror("创建线程 2 失败"); exit(EXIT_FAILURE); } // 设置第二个线程为分离状态 pthread_detach(tid2); // 主线程暂停 1 秒,等待子线程运行完毕 sleep(1); // 否则主线程太早结束,子线程可能还没执行就被强制终止 // 主线程结束 printf("主线程结束(不等待子线程)\n"); return 0; }