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

作业社区

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

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

Felixxx 的学生作业:

一、阻塞 I/O(Blocking I/O) 工作原理: 当应用程序发起一个 I/O 请求(如读取文件、接收网络数据)时,如果数据尚未就绪(例如缓冲区中没有数据),该调用会一直等待,直到数据准备好并完成拷贝到用户空间,才返回控制权给程序。在此期间,线程/进程处于阻塞状态,不能执行其他任务。 优点: 编程模型简单:代码逻辑清晰,易于理解和实现。 资源开销小:不需要频繁轮询或回调机制,系统开销较低。 适合低并发场景:在请求量不大、I/O 延迟可接受的情况下效率高。 缺点: 并发能力差:一个线程只能处理一个 I/O 请求,若需处理多个连接,必须创建多个线程/进程,导致资源消耗大。 响应延迟高:在高延迟 I/O(如网络请求)中,线程长时间阻塞,浪费 CPU 资源。 扩展性受限:面对成千上万并发连接时,线程数量激增,系统难以承受。 二、非阻塞 I/O(Non-blocking I/O) 工作原理: 当应用程序发起 I/O 请求时,如果数据未就绪,系统立即返回一个错误(如 EAGAIN 或 EWOULDBLOCK),而不是等待。程序可以继续执行其他任务,并在稍后再次尝试 I/O 操作(通常通过轮询或事件驱动机制判断数据是否就绪)。 优点: 高并发支持:单个线程可轮询或监听多个 I/O 操作,适合高并发场景(如 Web 服务器)。 资源利用率高:避免线程长时间阻塞,CPU 可用于处理其他任务。 响应更快:不会因某个 I/O 阻塞整个程序流程。 缺点: 编程复杂度高:需手动管理 I/O 状态、重试逻辑,通常需配合 select/poll/epoll 或异步框架。 轮询开销:若采用忙等待(busy-waiting)方式检查 I/O 状态,会浪费 CPU 资源。 调试困难:状态管理和错误处理更复杂,容易引入 bug。

得分 100
学习任务

Felixxx 的学生作业:

#include #include #include #include #include #include static int number = 0; //产品池 static bool done = false; static int active_producers = 0; static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; //互斥锁初始化 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //条件变量初始化 //生产者 void *producer_handler(void *arg) { int cnt = atoi((char *)arg); for(int i = 0;i < cnt;i++) { pthread_mutex_lock(&mtx); number++; printf("线程{%ld}生产一个产品,总产品数量为%d个\n",(long)pthread_self(),number); pthread_cond_broadcast(&cond); //提醒所有消费者 pthread_mutex_unlock(&mtx); usleep(1000); } pthread_mutex_lock(&mtx); active_producers--; if(active_producers == 0) { done = true; pthread_cond_broadcast(&cond); } pthread_mutex_unlock(&mtx); } //消费者 void *consumer_handler(void *arg) { while(1) { pthread_mutex_lock(&mtx); while(number == 0 && done == false) { pthread_cond_wait(&cond,&mtx); //wait后自动获得互斥锁 } if(number > 0) { number--; printf("线程{%ld}消费一个产品,产品数量为%d个\n",(long)pthread_self(),number); pthread_mutex_unlock(&mtx); usleep(1000); } else if(done == true) { pthread_mutex_unlock(&mtx); break; } } } int main(int argc,char *argv[]) { if(argc < 3) return EXIT_FAILURE; int consumer_count = 3; for(int i = 1;i < argc;i++) { if(strcmp(argv[i],"-c") == 0 && i+1 < argc) { consumer_count = atoi(argv[i+1]); break; } } //生产者 active_producers = argc -1 - (consumer_count > 0 ? 2:0); pthread_t producers[active_producers]; for(int i = 1,idx = 0 ; i < argc && idx < active_producers;i++) { if(strcmp(argv[i],"-c") == 0) { i++; continue; } pthread_create(&producers[idx++],NULL,producer_handler,argv[i]); } //消费者 pthread_t consumers[consumer_count]; for(int i = 0 ; i < consumer_count ; i++) pthread_create(&consumers[consumer_count],NULL,consumer_handler,NULL); //等待线程结束 for(int i = 0 ; i < active_producers ; i++) pthread_join(producers[i],NULL); for(int i = 0 ; i < consumer_count ; i++) pthread_join(consumers[i],NULL); printf("任务完成,剩余%d个产品\n",number); return 0; }

微信客服

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

帮助反馈 APP下载

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

公众号

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