【发布时间】:2020-04-29 20:52:54
【问题描述】:
我正在使用 C 语言中的 pthreads。我有线程 1 从一个硬件接收数据,并将该数据放入队列中。当数据在队列中并处理该数据时,我有线程 2 会收到通知。我的实际代码的伪代码如下。
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
void* inputThread(void *ptr){
while(){
getData(var1); //Notified by external hardware interrupt when data is available. var1 will hold new data
enqueue(q1, var1);
pthread_mutex_lock(&lock1);
pthread_cond_signal(&condition1);
pthread_mutex_unlock(&lock1);
}
}
void* processDataThread(void *ptr){
short data_to_process[];
while(){
pthread_mutex_lock(&lock1);
while (emptyqueue(q1)) {
pthread_cond_wait(&condition1,&lock1); //wait for inputthread to fill queue
}
data_to_process=dequeue(q1);
pthread_mutex_unlock(&lock1);
process_data(data_to_process); //causes thread to slow down
}
}
int main(void){
pthread_t input_thread_id;
pthread_t thr[10];
struct queue q1;
struct queue q2;
//
//
//some code to initiate queues, locks/mutex, conditions, etc.
//
//
for (j) {
pthread_create(&thr[j], NULL, processDataThread,(void*) &ptr);
}
sleep(3); //sleep to let processthreads start up
pthread_create(&input_thread_id, NULL, inputThread,(void*) &ptr);
}
我确信入队和出队工作正常。我写了一个文件并验证了我在 inputThread 中收到的任何内容都已出列。将process_data() 函数放入代码时出现问题。该函数会减慢 processDataThread 的速度,导致 inputThread 在 processDataThread 可以出队之前填满队列。这会导致丢失数据,因为 inputThread 的工作速度比 processDataThread 快。如果我注释掉 `process_data()' 函数,队列不会溢出。即使增加了 processDataThreads 的数量(我尝试了 3、5 和 10 个),队列的入队速度仍然比出队快。
runtime getData() to dequeue() 为 0.01s,程序连续循环运行,没有队列填充
getData() 到 process_data() 的运行时间是 0.05 秒,几秒钟后队列就会填满。
我做错了什么?我认为增加 processDataThread 的数量会比 dequeue 更快地解决入队问题,但事实并非如此。
【问题讨论】:
-
有多少个内核可用? process_data cpu 绑定了吗?
-
也许这只是一个错字,但 enqueue 函数不应该在关键部分内吗?而且增加队列大小根本没有帮助?
-
这毫无意义:
pthread_mutex_lock(&lock1); pthread_cond_signal(&condition1); pthread_mutex_unlock(&lock1);...好吧,没有我想象的那么糟糕。只是效率低下。对pthread_cond_signal的调用应该在enqueue内部,并且在释放锁之前调用 -
请提供一个最小的、可运行的问题演示。见minimal reproducible example
-
@AnaKhorguani 我的印象是,由于只有一个线程一直在排队,它不必在关键部分内。 Enqueue 只涉及 tail,而 dequeue 涉及 head。出队在关键部分内,因为超过 1 个线程访问该函数。