我写了一个程序,但它没有像我预期的那样工作。
我有两个线程:thread 触发 func 和 anotherThread 触发 anotherFunc。我想做的是当 cont 在 func 中达到值 10 时,使用 触发 和 anotherThread pthread_cond_waitpthread_cond_signal。奇怪的是,如果我取消注释 sleep(1) 行,一切正常。我是线程的新手,我正在学习教程 here如果我在他们的示例中评论 sleep 行,它也会中断。
我的问题是如何在没有任何 sleep() 调用的情况下完成这项工作?如果在我的代码中 func 在 anotherFunc 之后到达 pthread_mutex_lock 会发生什么?我怎样才能控制这些东西?这是我的代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t myMutex;
pthread_cond_t cond;
pthread_attr_t attr;
int cont;
void *func(void*)
{
printf("func\n");
for(int i = 0; i < 20; i++)
{
pthread_mutex_lock(&myMutex);
cont++;
printf("%d\n", cont);
if(cont == 10)
{
printf("signal:\n");
pthread_cond_signal(&cond);
// sleep(1);
}
pthread_mutex_unlock(&myMutex);
}
printf("Done func\n");
pthread_exit(NULL);
}
void *anotherFunc(void*)
{
printf("anotherFunc\n");
pthread_mutex_lock(&myMutex);
printf("waiting...\n");
pthread_cond_wait(&cond, &myMutex);
cont += 10;
printf("slot\n");
pthread_mutex_unlock(&myMutex);
printf("mutex unlocked anotherFunc\n");
printf("Done anotherFunc\n");
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t thread;
pthread_t anotherThread;
pthread_attr_init(&attr);
pthread_mutex_init(&myMutex, NULL);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_cond_init(&cond, NULL);
pthread_create(&anotherThread, &attr, anotherFunc, NULL);
pthread_create(&thread, &attr, func, NULL);
pthread_join(thread, NULL);
pthread_join(anotherThread, NULL);
printf("Done MAIN()");
pthread_mutex_destroy(&myMutex);
pthread_cond_destroy(&cond);
pthread_attr_destroy(&attr);
pthread_exit(NULL);
return 0;
}
抱歉发了这么长的帖子,但我是线程的新手,我愿意学习。您还知道有关 Linux 线程和网络的一些很好的引用资料或类(class)/教程吗?我想学习创建一个聊天客户端,我听说为此我必须了解线程和网络。问题是我不知道我学到的东西是否还好,因为我不知道我必须知道什么。
非常感谢:)
最佳答案
您的 anotherThread 只是简单地调用 pthread_cond_wait,而没有首先测试所需的条件(计数器达到 10)是否已经发生。这是不正确的逻辑,会导致唤醒丢失问题:困扰错误编写的多线程程序的反复出现的错误的名称。
条件变量是无状态的。如果在当前没有线程等待的情况下调用 pthread_cond_signal 或 pthread_cond_broadcast,则该操作无效。它不记得了。因此,您的信号线程有可能很快计数到 10,并在另一个线程到达 pthread_cond_wait 调用之前向条件变量发出信号。
您需要围绕 pthread_cond_wait 进行循环。如果条件已经为真,则必须检查条件,以便线程不会等待已经发生的唤醒。它应该是一个循环,因为唤醒可能是虚假的:仅仅因为线程通过 pthread_cond_wait 并不意味着条件实际上是真的:
while (cont < 10)
pthread_cond_wait(&cond, &myMutex);
另外,没有必要仅仅为了使线程可连接而创建线程属性。当您为创建属性使用空指针时,这是默认情况。 POSIX 线程是可连接的,除非创建为分离的,或者使用 pthread_detach 转换为分离的。
另一件事:只要有可能,避免在持有互斥锁时调用pthread_cond_signal。这并没有错,但它可能是一种浪费,因为该操作实际上可能必须调用操作系统内核来唤醒线程,因此您在整个系统调用中持有这个昂贵的互斥锁(当您真正需要它时)正在保护一些在您的应用程序中使用共享数据的机器指令)。
关于c++ - POSIX C 线程。 pthread_cond_t 示例。没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10179546/
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("