当前位置: 首页 > 知识库问答 >
问题:

c - 多线程任务问题?

李意致
2023-12-30

各位大佬请教一个问题,当我实现任务队列时rpushTasksQueue始终要比我上限少一个,比如我设定的上限是3,然后他2执行完就结束了,求救

#include <stdio.h>#include "config.h"#include "queue.h"// 初始化任务队列void initTasksQueue(struct TasksQueue* queue) {    for (int i = 0; i < MAX_THREADS; i++) {        printf("[*] 初始化任务队列[%d]\n",i);        queue->front[i][0] = queue->rear[i][0] = -1;    }}// 获取任务队列总数int getTasksQueueCount(struct TasksQueue* queue, int thread_id) {    // 如果头指针和尾指针的值都等于-1,代表该队列为空    if (queue->front[thread_id][0]  == -1 && queue->rear[thread_id][0] == -1) {        return 0;    }    // 计算任务中的总数:(尾指针-头指针+最大任务数)%最大任务数,如:(1-0+2)%2    printf("%d当前任务数%d\n",thread_id,(queue->rear[thread_id][0] - queue->front[thread_id][0] + MAX_TASKS_PER_THREAD) % MAX_TASKS_PER_THREAD);    return (queue->rear[thread_id][0] - queue->front[thread_id][0] + MAX_TASKS_PER_THREAD) % MAX_TASKS_PER_THREAD;}// 获取负载最低队列idint getIdleTasksQueueKey(struct TasksQueue* queue) {    // 初始化最小值为,队列数据上限    int min = MAX_TASKS_PER_THREAD;        // 初始化线程id,-1代表没有空闲    int task_thread_index = -1;        // 循环便利最大线程数    for (int i = 0; i < MAX_THREADS; i++) {        // 接收每个线程的任务总数        int count = getTasksQueueCount(queue, i);        if (count == 0) {            // 线程空闲时直接返回            return i;        }                // 线程里任务总数低于上限,小于上一次最小值,则本线程优先级最高        if (count < MAX_TASKS_PER_THREAD && count < min) {            min = count;            task_thread_index = i;        }    }        // 返回线程id    return task_thread_index;}// 入队int rpushTasksQueue(struct TasksQueue* queue, struct Task* task, int thread_id) {    // 检查当前队列是否为空,如果为空头指针和尾指针设置为0    if (queue->front[thread_id][0] == -1 && queue->rear[thread_id][0] == -1) {        queue->front[thread_id][0] = queue->rear[thread_id][0] = 0;    }        // 计算尾部指针移动后的位置:尾指针+1    int nextRear = (queue->rear[thread_id][0] + 1) % MAX_TASKS_PER_THREAD;    if (nextRear == queue->front[thread_id][0]) {        printf("[*] 线程[%d]已满\n",thread_id+1);        return 0;    }    // 数据写入    queue->tasks[thread_id][queue->rear[thread_id][0]] = *task;        // 移动指针    queue->rear[thread_id][0] = nextRear;    return 1;}// 出队int lpopTasksQueue() {    return 0;}
  // 模拟添加数据    for (int j = 0; j<5; j++) {            printf("\n\n[*] 当前第[%d]轮检查\n",j+1);            // 获取负载最低队列id            int getIdleTasksQueueKeyResult = getIdleTasksQueueKey(&tasksQueue);            printf("[*] 当前空闲线程[%d]\n",getIdleTasksQueueKeyResult+1);            if (getIdleTasksQueueKeyResult == -1) {                printf("[*] 当前没有空闲线程,稍后再试\n");                continue;            }                    struct Task task = {                .order_number="wwww",    // 订单号                .account="18210560183",            // 充值账号                .location="重庆",            // 归属地                .city="重庆",                    // 所属城市                .face_value=100        // 面值            };            int rpushTasksQueueResult = rpushTasksQueue(&tasksQueue, &task, getIdleTasksQueueKeyResult);            if (rpushTasksQueueResult == 1) {                printf("[*] 订单[]加入线程[%d]\n",getIdleTasksQueueKeyResult+1);            }        }

共有1个答案

邹俊拔
2023-12-30
# 多线程任务问题在多线程编程中,任务队列是一种常见的同步机制,用于在多个线程之间分配任务。然而,在使用任务队列时,可能会遇到一些问题,其中最常见的是"生产者-消费者"问题。"生产者-消费者"问题是一种经典的并发问题,其中生产者产生数据并放入队列,消费者从队列中取出数据并处理。当生产者的速度大于消费者的速度时,队列可能会溢出,导致数据丢失或程序崩溃。同样,当消费者的速度大于生产者的速度时,队列可能会耗尽,导致生产者空闲而消费者仍在等待。为了避免这些问题,可以使用一些同步机制来控制生产者和消费者的速度,例如使用条件变量、互斥锁或信号量等。此外,还可以使用循环缓冲区或固定大小的缓冲区来限制队列的大小,以避免队列溢出或耗尽。在你的代码中,你已经使用了循环缓冲区来限制队列的大小。然而,你的代码中存在一个问题,即在入队操作时没有检查队列是否已满。当队列已满时,你的代码仍然尝试将任务加入队列,这可能会导致队列溢出。为了解决这个问题,你可以在入队操作前添加一个检查队列是否已满的条件。如果队列已满,你可以选择等待一段时间再重试,或者将任务加入另一个队列或缓冲区,以等待有空闲线程时再处理。另外,你的代码中还有一些可以改进的地方。例如,在出队操作时没有处理队列为空的情况,这可能会导致程序崩溃或出现其他错误。你可以在出队操作前检查队列是否为空,如果为空则等待一段时间或处理其他任务。
 类似资料:
  • 多任务是一个操作系统可以同时执行多个程序的能力。基本上,操作系统使用一个硬件时钟为同时执行的每个程序配置「时间片段」。如果时间片段够小,并且机器也没有由于太多的程序而超出负荷时,那么在使用者看来,所有的这些程序似乎在同时执行着。 多任务并不是什么新的东西。在大型计算机上,多任务是必然的。这些大型主机通常有几十甚至几百个终端机和它连结,而每个终端机使用者都应该感觉到他或者她独占了整个计算机。另外,大

  • 我一直在四处寻找有类似问题的人,但没有找到任何东西。我正在编写一个使用WPF UI的C#应用程序。 为了更新progressbar,我不能像以前一样(在CLI中)使用多线程,因为它告诉我,如果UI元素不来自主线程,我就不能更新它。 一个解决方案是创建后台工作者。我已经实现了这个解决方案,它工作得很好,但是我希望将任务分配给更多的工作者/线程(多线程),以提高效率。 我不知道我该走的方向。如果有人能

  • 12.1.1 Windows 3.x的协同多任务 在16位的Windows 3.x中,应用程序具有对CPU的控制权。只有在调用了GetMessage、PeekMessage、WaitMessage或Yield后,程序才有可能把CPU控制权交给系统,系统再把控制权转交给别的应用程序。如果应用程序在长时间内无法调用上述四个函数之一,那么程序就一直独占CPU,系统会被挂起而无法接受用户的输入。 因此,在

  • 我正在尝试将一系列参数传递给不同的c线程。当NumThreads == 1时,程序运行良好,但是当NumThreads 创建线程的位置: 并且成员函数被调用: 来自前三个线程的控制台输出:{ 所以ID和样本索引被正确地传递给了线程,但是srcPoint怎么对所有三个线程都是相同的呢?!?

  • 问题内容: 我是python和线程的新手。我已经编写了充当网络爬虫的python代码,并在网站中搜索特定的关键字。我的问题是,如何使用线程同时运行类的三个不同实例。当实例之一找到关键字时,所有三个实例都必须关闭并停止爬网。这是一些代码。 如何使用线程让Crawler同时执行三个不同的爬网? 问题答案: 似乎没有一种(简单的)方法可以终止Python中的线程。 这是一个并行运行多个HTTP请求的简单

  • 主要内容:1 如何使用多个线程执行一个任务,2 如何使用多个线程执行多个任务1 如何使用多个线程执行一个任务 如果需要由多个线程执行单个任务,则只有一个run()方法,例如: 1.1 多个线程执行一个任务示例1 输出结果为: 1.2 多个线程执行一个任务示例2 输出结果为: 注意:每个线程在单独的堆栈中运行。 2 如何使用多个线程执行多个任务 如果必须通过多个线程执行多个任务,请使用多个run() 方法: 2.1 多个线程执行多个任务示例1 输出结果为: 2.2 多个线程