死锁和/或在线程死机之前返回
deadlock andor return before thread is dead
我在同样的情况下被困了大约 2 天,我真的很感激任何帮助。主线程正在调用 initDevice()
函数,该函数正在打开文件并创建一个新线程,他将成为具有 writeToDeviceHandler()
函数的"写入"线程。write2device()
是从main()调用的,应该插入新任务以写入(将来)到map<int,Task*>
。问题是,有时应用程序会卡在某种无限循环或死锁上,有时它会写入<(#个任务)来写入。任何人都可以看到代码中是否有任何问题吗?谢谢!
int write2device(char *buffer, int length)
{
if(is_running)
{
pthread_mutex_lock(&tasks_mutex);//LOCK
int curr_id = getNextAvailableId();
Task* new_task = new Task(buffer,length, curr_id);
tasks[curr_id] = new_task;
pthread_cond_signal(&tasks_cv);
given_ids.insert(curr_id);
pthread_mutex_unlock(&tasks_mutex);//UNLOCK
return curr_id;
}
return FAIL;
}
int initdevice(char *filename)
{
is_running = true;
pthread_cond_signal(&tasks_cv);
output_file.open(filename);
if(!output_file.is_open())
{
cerr << "Error opening file" << endl;
is_running = false;
return SYSTEM_ERROR;
}
int res = pthread_create(&writing_thread, NULL, writeToDeviceHandler, NULL);//Create the writing to file thread.
if(res != 0)
{
cerr << "Error creating the writing thread" <<endl;
exit(FAIL);
}
return SUCCESS;
}
void *writeToDeviceHandler(void *arg)
{
Task* curr_task;
while(is_running)
{
pthread_mutex_lock(&tasks_mutex);
cout << "IN LOOP - size of db: " << tasks.size() << endl;
if(tasks.empty())
{
pthread_cond_wait(&tasks_cv, &tasks_mutex);
}
if(tasks.empty()) cout << "Empty, still finding thread" <<endl;
curr_task = tasks.begin()->second;
if(curr_task == NULL)
{
pthread_mutex_unlock(&tasks_mutex);
continue;
}
//copy from tasks to file
output_file.write(curr_task->getBuff(), curr_task->getLength());
ids.remove(curr_task->getId());
tasks.erase(curr_task->getId());
delete curr_task;
pthread_mutex_unlock(&tasks_mutex);
}
pthread_exit(NULL);
return NULL;
}
您的代码不正确,因为它没有围绕pthread_cond_wait
调用的循环。pthread_cond_wait
调用可能会在虚假唤醒时返回。您必须在它返回后检查您的唤醒状况。在您的情况下,它看起来像这样:
while (task.empty ())
pthread_cond_wait(&tasks_cv, &tasks_mutex);
您的代码也缺少错误检查。请检查所有函数的所有返回值是否存在错误。
您的writeToDeviceHandler
代码在持有互斥锁的同时完成所有工作,完全违背了线程的意义。如果另一个线程想要给这个线程工作,它将不得不获取tasks_mutex
。为此,它必须完成,直到此线程完成写入并释放互斥锁。那么为什么要打扰这个线程呢?
当您有一个保护需要完成的工作的互斥锁时,重点是实际使用释放的互斥锁来执行工作。这样,其他线程就不必等待您完成工作。
相关文章:
- 从C++本机插件更新Vector3数组
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 如果我对"while"块发表评论,为什么程序会死机?其中的"yield"线有何影响?
- 从本机代码返回到托管代码会损坏返回的对象
- 将返回的类型分配给一个脱口机类型
- 从本机代码返回"const char*"并在java中获取"字符串"
- SQLExecDirect 在死锁时不返回
- 从SQL Server返回C++本机客户端中的NULL数据类型
- 本机 WMI 提供程序中的 UINT64 不返回某些系统上的数据
- 死锁和/或在线程死机之前返回
- 从DLL调用的C++方法返回Adobe Air本机扩展中以前调用的数据
- 通过.NET中的指针从本机方法返回数据
- 如何从本机函数返回QAndroidJniObject
- 如何在并行编程中收集从机到主机返回的值
- 如何在Windows Azure中从本机代码返回字符串到托管代码
- 如何同时在本机 dll 中返回整数和字符 * 变量C++?
- 使用NDK从本机内存恢复图像会返回无显示的黑色图像
- Windows 8.1运行c++程序后死机