当前位置: 首页 > news >正文

北京棋森建设有限公司网站wordpress转pdf

北京棋森建设有限公司网站,wordpress转pdf,洛阳网络公司排名,祥云平台网站建设怎么收费2.3 实践与案例分析 2.3.1 案例分析#xff1a;多线程文件搜索程序 本文中#xff0c;我们将通过一个多线程文件搜索程序的案例#xff0c;展示如何在实际项目中应用多线程编程技术#xff0c;并具体介绍任务分解、线程创建、结果汇总及锁机制的应用。 2.3.1.1 任务分解…2.3 实践与案例分析 2.3.1 案例分析多线程文件搜索程序 本文中我们将通过一个多线程文件搜索程序的案例展示如何在实际项目中应用多线程编程技术并具体介绍任务分解、线程创建、结果汇总及锁机制的应用。 2.3.1.1 任务分解与线程创建 在一个多线程文件搜索程序中我们首先需要将搜索任务分解为多个子任务每个子任务由一个线程执行。 任务分解将整个文件夹树的搜索任务分解成若干个独立的搜索路径每个线程负责一个或多个搜索路径。这种方式能够充分利用多核CPU提高搜索效率。线程创建利用POSIX线程库中的 pthread_create 函数创建多个线程并让每个线程执行它们分配到的搜索任务。 #include stdio.h #include pthread.h #include string.h #include dirent.h#define MAX_THREADS 10// 线程函数声明 void* search_file(void *arg);// 任务结构体定义 typedef struct {char path[256]; // 搜索路径 [1]char target[256]; // 目标文件名 [2] } SearchTask;int main() {pthread_t threads[MAX_THREADS]; // 线程数组 [3]SearchTask task[MAX_THREADS]; // 任务数组 [4]// 初始化任务例如将 /home/user 作为搜索路径strcpy(task[0].path, /home/user); // 设置搜索路径 [5]strcpy(task[0].target, target_file.txt); // 设置目标文件 [6]// 创建线程if (pthread_create(threads[0], NULL, search_file, (void*)task[0])) { // 创建线程 [7]fprintf(stderr, Error creating thread\n);return 1;}// 等待线程完成for (int i 0; i MAX_THREADS; i) {pthread_join(threads[i], NULL); // 等待线程结束 [8]}return 0; }void* search_file(void *arg) {SearchTask *task (SearchTask*)arg; // 获取任务参数 [9]DIR *dir;struct dirent *entry; // 目录项结构指针// 打开目录if ((dir opendir(task-path)) NULL) { // 打开目录 [10]perror(opendir() error); // 处理打开失败情况return NULL;}// 读取目录项while ((entry readdir(dir)) ! NULL) { // 遍历目录项 [11]if (strcmp(entry-d_name, task-target) 0) { // 文件名匹配检查 [12]printf(Found file: %s/%s\n, task-path, task-target); // 找到目标文件 [13]break; // 找到文件后退出}}// 关闭目录closedir(dir);return NULL; }[1] 搜索路径char path[256] 用于存储待搜索的目录路径。[2] 目标文件名char target[256] 保存待查找的文件名。[3] 线程数组pthread_t threads[MAX_THREADS] 用于存储线程ID。[4] 任务数组SearchTask task[MAX_THREADS] 存储每个线程的搜索任务。[5] 设置搜索路径使用 strcpy() 函数初始化任务中路径。[6] 设置目标文件使用 strcpy() 函数初始化任务中目标文件名。[7] 创建线程使用 pthread_create() 函数创建线程并指定执行函数及其参数。[8] 等待线程结束pthread_join() 用于等待线程执行完毕以确保所有线程在程序结束前完成任务。[9] 获取任务参数将 void* arg 转换为 SearchTask*。[10] 打开目录opendir() 函数打开指定路径的目录返回目录指针。[11] 遍历目录项使用 readdir() 读取目录内容将结果存入 struct dirent* entry。[12] 文件名匹配检查strcmp() 判断目录项名称是否与目标文件名相同。[13] 找到目标文件匹配后打印出文件的完整路径。 2.3.1.2 线程间结果汇总 在一个多线程程序中各个线程需要将它们的搜索结果汇总到一个共享的数据结构中。为了确保线程安全汇总结果时需要使用同步机制。 共享数据结构可以使用一个全局链表或数组来存储搜索到的目标文件路径。线程安全在访问共享数据结构时使用互斥锁 (pthread_mutex_t) 来防止数据竞态条件。 #include pthread.h// 定义一个互斥锁 pthread_mutex_t lock;// 定义一个二维字符数组用于存储搜索结果 char results[10][256]; // 假设最多可以存储10个结果 [1]// 函数 search_file用于在文件中搜索 void* search_file(void *arg) {// ... 进行搜索的代码与前代码段一致 ...// 加锁以保证线程安全pthread_mutex_lock(lock);// 将结果存储到共享的 results 数组中strcpy(results[0], task-path); // 假设将结果存储到第一个位置 [2]// 解锁以允许其他线程访问pthread_mutex_unlock(lock);// ... 继续进行其余的搜索逻辑 ...return NULL; // 返回空指针表示线程无返回值 [3] }int main() {// 初始化互斥锁pthread_mutex_init(lock, NULL); // 使用默认属性初始化锁 [4]// 创建线程并等待其完成这部分代码在较早示例中提供// ... 线程创建及执行代码略 ...// 销毁互斥锁pthread_mutex_destroy(lock); // 销毁锁以释放系统资源 [5]return 0; }[1] 结果存储数组char results[10][256] 定义了一个二维数组能够存储最多10个字符串结果每个结果最长256字节。[2] 结果存储到共享数组strcpy(results[0], task-path); 此行示例中假设将结果存储在 results 数组的第一个位置。实际存储位置需要根据逻辑进行动态选择。[3] 返回空指针线程函数search_file不需要返回具体数据直接返回 NULL。[4] 初始化互斥锁pthread_mutex_init(lock, NULL); 用于初始化互斥锁NULL 表示使用默认的锁属性。[5] 释放锁资源pthread_mutex_destroy(lock); 销毁互斥锁以释放占用的系统资源这通常在主程序最后进行。 2.3.1.3 锁机制的应用 为了避免多个线程同时操作共享数据而导致竞态条件需要使用互斥锁机制来确保线程安全。 互斥锁在每次访问共享数据结构之前先锁住互斥锁 (pthread_mutex_lock)操作完成后解锁 (pthread_mutex_unlock)。应用场景在搜索结果的汇总过程中各个线程需要安全地将找到的结果存储到共享的数据结构中使用锁能确保各线程按照序列进行数据操作。 pthread_mutex_lock(lock); // 锁住数据 // 更新共享数据 pthread_mutex_unlock(lock); // 解锁数据以上内容详细讲解了多线程编程中任务分解、线程创建、结果汇总及锁机制的应用。通过这个案例您可以了解如何在实际项目中应用多线程技术提高程序的并发处理能力和效率。 2.3.2 案例分析生产者-消费者模型 2.3.2.1 问题描述与解决思路 生产者-消费者问题是一个经典的并发控制问题描述了两个线程或进程之间的互斥使用共享资源的情况。通常一个或多个生产者线程负责生产数据并放入一个共享的缓冲区而一个或多个消费者线程负责从缓冲区中取出数据进行处理。 问题描述 生产者不断地向缓冲区放入产品。消费者不断地从缓冲区取出产品。缓冲区有固定容量当缓冲区满时生产者必须等待当缓冲区空时消费者必须等待。 解决思路 使用互斥锁mutex保护对共享缓冲区的访问防止生产者和消费者同时操作缓冲区导致的数据不一致。使用信号量semaphore或条件变量condition variable来管理缓冲区的状态控制生产者和消费者的等待和唤醒。 2.3.2.2 信号量与互斥锁的结合使用 在生产者-消费者问题中信号量常用于管理缓冲区中的空闲位置和已有数据的数量而互斥锁则用于保护缓冲区的访问。 信号量 空闲位置信号量表示缓冲区中可放置产品的位置数量。已有数据信号量表示缓冲区中已有的产品数量。 互斥锁 这段代码展示了经典的生产者-消费者问题用缓冲区实现生产者生成产品消费者消费产品。生产者和消费者之间通过信号量和互斥锁进行同步和互斥控制。 #include stdio.h #include pthread.h #include semaphore.h #include stdlib.h#define BUFFER_SIZE 5int buffer[BUFFER_SIZE]; // 缓冲区 [1] int in 0, out 0; // 生产和消费的指针 [2]pthread_mutex_t mutex; // 互斥锁 [3] sem_t empty, full; // 信号量空槽和满槽 [4]// 生产者线程的函数 void *producer(void *param) {int item;while (1) {item rand() % 100; // 生产一个随机数 [5]sem_wait(empty); // 等待空闲位置 [6]pthread_mutex_lock(mutex); // 获取互斥锁保证对缓冲区操作的原子性 [7]buffer[in] item; // 将产品放入缓冲区 [8]in (in 1) % BUFFER_SIZE; // 环形缓冲区更新生产序号 [9]printf(Produced: %d\n, item);pthread_mutex_unlock(mutex); // 释放互斥锁 [10]sem_post(full); // 增加已有产品数量 [11]} }// 消费者线程的函数 void *consumer(void *param) {int item;while (1) {sem_wait(full); // 等待已有产品 [12]pthread_mutex_lock(mutex); // 获取互斥锁保证对缓冲区操作的原子性 [13]item buffer[out]; // 从缓冲区取出产品 [14]out (out 1) % BUFFER_SIZE; // 环形缓冲区更新消费序号 [15]printf(Consumed: %d\n, item);pthread_mutex_unlock(mutex); // 释放互斥锁 [16]sem_post(empty); // 增加空闲位置数量 [17]} }// 主函数 int main() {pthread_t prod, cons;pthread_mutex_init(mutex, NULL); // 初始化互斥锁 [18]sem_init(empty, 0, BUFFER_SIZE); // 初始化信号量 empty初始值为 BUFFER_SIZE表示起始时所有位置都是空的 [19]sem_init(full, 0, 0); // 初始化信号量 full初始值为 0表示起始时一个产品都没有 [20]pthread_create(prod, NULL, producer, NULL); // 创建生产者线程 [21]pthread_create(cons, NULL, consumer, NULL); // 创建消费者线程 [22]pthread_join(prod, NULL); // 阻塞主线程等待生产者线程结束 [23]pthread_join(cons, NULL); // 阻塞主线程等待消费者线程结束 [24]pthread_mutex_destroy(mutex); // 销毁互斥锁 [25]sem_destroy(empty); // 销毁信号量 empty [26]sem_destroy(full); // 销毁信号量 full [27]return 0; }详细注释 [1] 缓冲区用于存储生产者产生而等待被消费者消费的产品。[2] 生产和消费的指针in指向下一个将存入产品的位置out指向将被消费的产品位置。两者实现环形缓冲区的指针管理。[3] 互斥锁保护对共享缓冲区的访问确保同一时刻只有一个线程进行写入或读取操作。[4] 信号量empty和full empty表示缓冲区中空余的槽位。full表示缓冲区中已满的槽位以便消费者知道是否有产品可以消费。 [5] 生产随机产品使用rand()函数生成随机数模拟产品生产。[6] 等待空闲位置通过sem_wait(empty)若empty信号量为0则线程会被阻塞直到有槽位可用。[7] 获取互斥锁确保对共享资源操作的独占性。[8] 存放产品将生产的产品放入缓冲区指定位置。[9] 环形缓冲区更新生产器位置in的循环递增。[10] 释放互斥锁操作完成后释放锁。[11] 增加产品数量信号量full增加表示多一个产品可消费。[12] 等待已有产品通过sem_wait(full)若full信号量为0则线程会被阻塞直到有产品可用。[13] 获取互斥锁确保对共享资源操作的独占性。[14] 消费产品从缓冲区的指定位置取出产品。[15] 环行缓冲区更新消费者位置out的循环递增。[16] 释放互斥锁操作完成后释放锁。[17] 增加空闲位置信号量empty增加表示多一个槽位可用。[18] 初始化互斥锁对mutex进行初始化准备使用。[19] 初始化信号量empty信号量empty表示初始时所有位置都是空的。[20] 初始化信号量full初始值为0表示起始时没有产品可以消费。[21-22] 创建线程分配并启动生产者和消费者线程。[23-24] 等待线程结束pthread_join用于等待线程结束确保主线程不会提前退出。[25-27] 资源销毁销毁锁和信号量释放资源。 2.3.2.3 条件变量的应用 条件变量提供了一种线程间通知的机制。一个线程可以等待特定的条件变量另一个线程可以在条件变量上发出信号通知等待的线程条件已经满足。 在生产者-消费者问题中可以用条件变量实现对缓冲区状态的检查和通知。 代码示例 #include stdio.h #include pthread.h #include stdlib.h // 添加stdlib.h用于rand()#define BUFFER_SIZE 5int buffer[BUFFER_SIZE]; // 循环缓冲区 [1] int in 0, out 0; // 生产者和消费者指针 [2]pthread_mutex_t mutex; // 互斥锁 [3] pthread_cond_t not_full, not_empty; // 条件变量 [4]// 生产者线程函数 void *producer(void *param) {int item;while (1) {item rand() % 100; // 生成随机数 [5]pthread_mutex_lock(mutex); // 获取互斥锁 [6]while ((in 1) % BUFFER_SIZE out) {pthread_cond_wait(not_full, mutex); // 缓冲区满时等待 [7]}buffer[in] item; // 放入缓冲区 [8]in (in 1) % BUFFER_SIZE;printf(Produced: %d\n, item);pthread_cond_signal(not_empty); // 通知消费者 [9]pthread_mutex_unlock(mutex); // 释放互斥锁 [10]} }// 消费者线程函数 void *consumer(void *param) {int item;while (1) {pthread_mutex_lock(mutex); // 获取互斥锁 [11]while (in out) {pthread_cond_wait(not_empty, mutex); // 缓冲区空时等待 [12]}item buffer[out]; // 提取缓冲区产品 [13]out (out 1) % BUFFER_SIZE;printf(Consumed: %d\n, item);pthread_cond_signal(not_full); // 通知生产者 [14]pthread_mutex_unlock(mutex); // 释放互斥锁 [15]} }int main() {pthread_t prod, cons;// 初始化互斥锁和条件变量 [16]pthread_mutex_init(mutex, NULL);pthread_cond_init(not_full, NULL);pthread_cond_init(not_empty, NULL);// 创建生产者和消费者线程 [17]pthread_create(prod, NULL, producer, NULL);pthread_create(cons, NULL, consumer, NULL);// 等待线程结束不会发生[18]pthread_join(prod, NULL);pthread_join(cons, NULL);// 销毁互斥锁和条件变量 [19]pthread_mutex_destroy(mutex);pthread_cond_destroy(not_full);pthread_cond_destroy(not_empty);return 0; }[1] 循环缓冲区定义一个大小为5的整数数组用于存储生产者生成的数据。[2] 生产者和消费者指针in和out用于指示生产和消费的位置基于环形缓冲区机制确保指针在0到BUFFER_SIZE-1之间循环利用。[3] 互斥锁pthread_mutex_t mutex用于确保对共享缓冲区的互斥访问以避免竞争条件。[4] 条件变量not_full 和 not_empty 用于生产者和消费者之间的同步确保缓冲区状态改变时进行相应的阻塞或唤醒。[5] 生成随机数生产者生成0-99之间的随机整数作为产品。[6] 获取互斥锁生产者在向缓冲区中放入产品之前锁定互斥锁确保独占访问。[7] 缓冲区满时等待如果缓冲区满则生产者在not_full条件变量上等待直至消费者消耗产品。[8] 放入缓冲区将生成的产品放入缓冲区并更新生产者索引。[9] 通知消费者生产者生产完产品后通过pthread_cond_signal()通知可能在等待的消费者。[10] 释放互斥锁对于共享数据操作完成后释放锁允许其他线程访问。[11] 获取互斥锁消费者在从缓冲区中消费产品之前锁定互斥锁。[12] 缓冲区空时等待如果缓冲区为空消费者在not_empty条件变量上等待直至生产者提供产品。[13] 提取缓冲区产品从缓冲区中取出产品并更新消费者索引。[14] 通知生产者消费者取完产品后通过pthread_cond_signal()通知可能在等待的生产者。[15] 释放互斥锁消费者完成操作后释放互斥锁。[16] 初始化互斥锁和条件变量在程序开始时初始化全局同步资源。[17] 创建生产者和消费者线程使用pthread_create()启动生产者和消费者线程。[18] 等待线程结束不会发生主线程等待生产者和消费者结束但由于它们是无限循环因此不会发生。[19] 销毁互斥锁和条件变量程序结束时清理资源。不实际发生在这段代码中因为程序永远运行。 总结 在生产者-消费者模型中通过信号量和互斥锁可以有效地管理生产和消费的过程避免竞争条件。而条件变量提供了更灵活的线程间通知机制可以更精确地控制生产者和消费者的互相等待和唤醒。 2.3.3 案例分析读写者问题 读写者Reader-Writer问题是经典的并发控制问题之一。在这个问题中存在多个读者Reader和多个写者Writer读者可以同时读取数据而写者在执行写操作时需要保证没有其他读者或写者。 2.3.3.1 问题描述与解决方案 问题描述 在共享数据的并发访问中需要满足以下条件 当一个写者正在写数据时不允许任何读者或者写者访问数据。当一个读者正在读数据时允许其他读者继续读但不允许写者写数据。 问题解决方案 为了解决读写者问题可以使用读写锁Reader-Writer Lock。读写锁允许多个读者同时读取数据但在有写者进行写操作时会锁定读访问和写访问。 2.3.3.2 读写锁的使用 使用POSIX线程库中的读写锁可以有效解决读写者问题以下是一个基本使用示例 #include pthread.h #include stdio.h #include stdlib.h #include unistd.h#define NUM_READERS 5 // 定义读者线程数量 [1] #define NUM_WRITERS 2 // 定义写者线程数量 [2]pthread_rwlock_t rwlock; // 声明读写锁 [3] int shared_data 0; // 共享数据资源 [4]// 读者线程函数 void* reader(void* arg) {int id *((int*)arg);while (1) {pthread_rwlock_rdlock(rwlock); // 获取读锁 [5]printf(Reader %d: read shared_data %d\n, id, shared_data);pthread_rwlock_unlock(rwlock); // 释放读锁 [6]sleep(1);}return NULL; }// 写者线程函数 void* writer(void* arg) {int id *((int*)arg);while (1) {pthread_rwlock_wrlock(rwlock); // 获取写锁 [7]shared_data;printf(Writer %d: updated shared_data to %d\n, id, shared_data);pthread_rwlock_unlock(rwlock); // 释放写锁 [8]sleep(2);}return NULL; }int main() {pthread_t readers[NUM_READERS], writers[NUM_WRITERS];int ids[NUM_READERS NUM_WRITERS ? NUM_READERS : NUM_WRITERS];pthread_rwlock_init(rwlock, NULL); // 初始化读写锁 [9]// 创建读者线程for (int i 0; i NUM_READERS; i) {ids[i] i 1;pthread_create(readers[i], NULL, reader, ids[i]); // 创建读者线程 [10]}// 创建写者线程for (int i 0; i NUM_WRITERS; i) {ids[i] i 1;pthread_create(writers[i], NULL, writer, ids[i]); // 创建写者线程 [11]}// 等待所有线程完成for (int i 0; i NUM_READERS; i) {pthread_join(readers[i], NULL); // 等待读者线程终止 [12]}for (int i 0; i NUM_WRITERS; i) {pthread_join(writers[i], NULL); // 等待写者线程终止 [13]}pthread_rwlock_destroy(rwlock); // 销毁读写锁 [14]return 0; }[1] 读者线程数量#define NUM_READERS 5 表示创建5个读者线程。[2] 写者线程数量#define NUM_WRITERS 2 表示创建2个写者线程。[3] 读写锁声明pthread_rwlock_t rwlock 用于同步对共享数据的访问。[4] 共享数据资源变量 shared_data 是所有线程共享访问的整数。[5] 获取读锁pthread_rwlock_rdlock 保证能安全地读共享数据。[6] 释放读锁pthread_rwlock_unlock 在读数据结束后释放锁以允许其他线程访问。[7] 获取写锁pthread_rwlock_wrlock 为写者线程获取独占访问权。[8] 释放写锁pthread_rwlock_unlock 在写操作结束后释放锁。[9] 初始化读写锁pthread_rwlock_init 函数用于读写锁的初始化处理。[10] 创建读者线程pthread_create 启动指定数量的读者线程。[11] 创建写者线程pthread_create 启动指定数量的写者线程。[12] 等待读者线程终止pthread_join 用于等待对应的读者线程执行结束。[13] 等待写者线程终止pthread_join 用于等待对应的写者线程执行结束。[14] 销毁读写锁pthread_rwlock_destroy 清理和释放读写锁的资源。 这段代码示例了一个经典的读者-写者问题的同步解决方案确保多个读者可以并发地读取资源但只允许一个写者可以更新资源。 2.3.3.3 优化与性能分析 优化建议 读优先 vs 写优先根据应用场景可以设置锁的策略例如优先读还是优先写。可以通过调整锁的使用顺序防止读者或写者饥饿。线程设计在实际程序中可以根据读写操作频率调整读者和写者的数量。调整锁策略如果共享数据的访问频率较高可以考虑减少锁的争用。例如通过分段锁定减少锁的冲突。 性能分析 使用读写锁显著提高了并发性因为读操作不相互干扰。但需要注意的是如果写操作频繁可能导致读操作的延迟。因此对于高并发的读操作读写锁是有效的但如果有大量的写操作需求可能需要重新审视锁策略或者使用其他并发控制机制。 通过本文中读写锁的基本介绍及实际代码示例可以帮助解决经典的读写者问题提升对并发编程的理解与应用能力。 上述解释包括了对读写者问题的描述引入了读写锁的相关概念并通过实际的C语言代码展示了如何使用读写锁最后对优化措施和性能进行了简单分析。
http://www.dnsts.com.cn/news/268545.html

相关文章:

  • 顺德网站建设市场企业网站模板免费下载
  • asp网站后台密码破解免费创建音乐网站
  • 临沂做拼多多网站邯郸网站建设浩森宇特
  • 咖啡网站设计模板网站建设目录结构doc
  • 网站做一样没有侵权吧安顺seo
  • 中国互联网站建设中心做页面设计的网站
  • yw12777域名查询网站seo啥意思
  • 绍兴网站建设公司网络营销策略定义
  • 用asp.net做简易网站东莞网站优化方式
  • 怎么做样网站潍坊logo设计公司
  • 顺德网站建设公司价位客户网站建设需要什么资料
  • 邯郸网站维护wordpress电话注册
  • php 网站cookiewordpress中国加速
  • 哪些网站动效做的不错响应式网站的制作工具
  • 郑州营销网站公司地址男的和女的做那个视频网站
  • 国外婚纱网站建设现状263云通信官方网站
  • 怎样运营网站阿里云自助建站模板
  • 做五金生意什么网站做比较好企业查询官网入口
  • 外贸公司网站多少钱手工包网站建设策划书
  • 网站备案怎么更改吗微信开发者平台教程
  • 网站关键词设置多少个Wordpress視頻加密
  • 网站备案前置审批表免费域名网站黄的免费
  • 珠海建设集团网站首页网站设计理念介绍
  • 网站建设实训要求关键词大全
  • 的推网站模板百度公司排名
  • 医疗网站模板网匠网站建设有限公司
  • 教如何做帐哪个网站好网站模板怎么做视频教程
  • 成都哪里有做网站的公司phpcms学校网站模板
  • 移动端的网站电商怎么做流量
  • 做企业英语网站要注意哪些广元网页制作公司