- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我已经有很长时间的线程问题了。这段代码应该让工作线程在主线程打印出来时增加共享整数的值。但是,我没有得到预期的输出。
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
pthread_mutex_t lock;
int shared_data = 0; //shared data
// Often shared data is more complex than just an int.
void* thread_function(void* arg)
{
int i;
for (i = 0; i < 10; ++i)
{
// Access the shared data here.
pthread_mutex_lock(&lock);
shared_data++;
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main(void)
{
pthread_t thread;
int i;
void* exit_status;
// Initialize the mutex before trying to use it.
pthread_mutex_init(&lock, NULL);
pthread_create(&thread, NULL, thread_function, NULL);
// Try to use the shared data.
for (i = 0; i < 10; ++i)
{
sleep(1);
pthread_mutex_lock(&lock);
printf ("\r for i= %d Shared integer 's value = %d\n", i, shared_data);
pthread_mutex_unlock(&lock);
}
printf("\n");
pthread_join(thread, &exit_status);
// Clean up the mutex when we are finished with it.
pthread_mutex_destroy(&lock);
return 0;
}
这是我期望的:
for i=0 Shared Integer 's value = 0
for i=1 Shared Integer 's value = 1
for i=3 Shared Integer 's value = 2
...
for i=10 Shared Integer 's value =10
但结果是:
for i=0 Shared Integer 's value = 0
for i=1 Shared Integer 's value = 10
for i=3 Shared Integer 's value = 10
...
for i=10 Shared Integer 's value =10
那么我该如何解决呢?
最佳答案
主线程和你的工作线程同时运行。也就是说,如果没有额外的同步,让那些 for 循环彼此完美重合几乎是不可能的。
您的输出正是您所期望的。生成线程所花费的时间允许主线程在其他线程更改共享数据之前进行打印。然后,打印花费的时间太长,以至于另一个线程完全完成其循环并在主线程可以进行第二次迭代之前将共享数据递增到 10。
在一个完美的世界中,这个使用条件变量的小 hack 会得到你想要的:编辑:条件变量对此不是一个好主意。这是使用伪原子变量并且不包含 UB :) 的工作版本:
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
pthread_mutex_t want_incr_mut;
pthread_mutex_t done_incr_mut;
int want_incr = 0;
int done_incr = 0;
int shared_data = 0; //shared data
// Not using atomics, so...
void wait_for_want_increment()
{
while (1)
{
pthread_mutex_lock(&want_incr_mut);
if (want_incr)
{
pthread_mutex_unlock(&want_incr_mut);
return;
}
pthread_mutex_unlock(&want_incr_mut);
}
}
void wait_for_done_incrementing()
{
while (1)
{
pthread_mutex_lock(&done_incr_mut);
if (done_incr)
{
pthread_mutex_unlock(&done_incr_mut);
return;
}
pthread_mutex_unlock(&done_incr_mut);
}
}
void done_incrementing()
{
pthread_mutex_lock(&done_incr_mut);
done_incr = 1;
pthread_mutex_lock(&want_incr_mut);
want_incr = 0;
pthread_mutex_unlock(&want_incr_mut);
pthread_mutex_unlock(&done_incr_mut);
}
void want_increment()
{
pthread_mutex_lock(&want_incr_mut);
want_incr = 1;
pthread_mutex_lock(&done_incr_mut);
done_incr = 0;
pthread_mutex_unlock(&done_incr_mut);
pthread_mutex_unlock(&want_incr_mut);
}
// Often shared data is more complex than just an int.
void* thread_function(void* arg)
{
int i;
for (i = 0; i < 10; ++i)
{
wait_for_want_increment();
// Access the shared data here.
shared_data++;
done_incrementing();
}
return NULL;
}
int main(void)
{
pthread_t thread;
int i;
void* exit_status;
// Initialize the mutex before trying to use it.
pthread_mutex_init(&want_incr_mut, NULL);
pthread_mutex_init(&done_incr_mut, NULL);
pthread_create(&thread, NULL, thread_function, NULL);
// Try to use the shared data.
for (i = 0; i <= 10; ++i)
{
printf("\r for i= %d Shared integer 's value = %d\n", i, shared_data);
if (i == 10) break;
want_increment();
wait_for_done_incrementing();
}
printf("\n");
pthread_join(thread, &exit_status);
// Clean up the mutexes when we are finished with them.
pthread_mutex_destroy(&want_incr_mut);
pthread_mutex_destroy(&done_incr_mut);
return 0;
}
在这里,我们只是告诉工作人员我们想要一个增量,并在我们继续之前等待他说他完成了。同时, worker 等待我们想要增量并告诉我们他什么时候完成。
我还将主循环更改为十,因为我认为这是您想要的。
这是我的输出:
for i= 0 Shared integer 's value = 0
for i= 1 Shared integer 's value = 1
for i= 2 Shared integer 's value = 2
for i= 3 Shared integer 's value = 3
for i= 4 Shared integer 's value = 4
for i= 5 Shared integer 's value = 5
for i= 6 Shared integer 's value = 6
for i= 7 Shared integer 's value = 7
for i= 8 Shared integer 's value = 8
for i= 9 Shared integer 's value = 9
for i= 10 Shared integer 's value = 10
关于与线程同步混淆 [pthreads],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44170564/
我真的很困惑。我已经尝试使用带有 tomcat 的 Jax-rs 并使用所有注释,我能够使用 url 调用我的服务。因此,如果没有 Jax-rs,我可以简单地拥有一个 servlet 并调用我的服务。
是否有任何工具/商业混淆器可以混淆 WPF 控件中的 BAML 资源? 如果没有,就 IP 保护而言,这是一段艰难的时期,因为黑客可以通过使用 BAML 到 XAML 转换器轻松查看 BAML 资源。
嘿大家。我在尝试使用 COBOL 在 zOS 环境中解决的编码项目中遇到了一些麻烦。我需要读入一个文件并将它们放入索引表中(我知道将少于 90 条记录)。 让我感到困扰的是,我们受到项目参数的约束,以
我试图按照这个例子来理解 join() 方法: class PrintDemo { public void printCount() { try { for(int
当我编译我正在编写的代码,然后在 JD Gui 中查看时,方法显示带有如下标题: public void growSurface(Random paramRandom, int paramInt1,
我正在为重新分发准备 Android 库,它的代码必须进行混淆处理。我已经阅读了有关此主题的一些内容,并且决定使用 Android Library Project。它将作为 jar 分发(自动在/bi
两个混淆相关的问题: 1) 是否有任何工具可以将 F# 从 MSIL 目标形式反汇编回其源形式或接近它的形式?这不是通过默默无闻来实现安全性的尝试,但我想保护某些源代码免遭“盗窃”。 2) 我简要地查
谁能向我解释为什么 simulatedCase <- rbinom(100,1,0.5) simDf <- data.frame(CASE = simulatedCase) posterior_m0
我一直无法找到关于使用 AppDomains 时发生的事情的非常清楚的描述,所以希望有人能够启发我。我有一个简单的测试程序(基本上是扯掉了 MSDN example ): using System;
假设我有 2 个分支topic和 master如果我在 topic分支,然后运行 git rebase master它是 rebase master 还是 rebase 主题分支? 做 git r
我有一个类(class): public class LockTest { public void LockThis() { lock (this)
我正在尝试最小化/混淆我的 Angular 代码,但遇到了问题。我在这里阅读“缩小说明”http://docs.angularjs.org/tutorial/step_05但我定义我的 Control
我遇到了一些困惑的操作。 var a = 0.1; var b = 0.2; var c = 0.3; console.log(a); // 0.1 console.log(b); // 0.2 co
感谢您查看我的帖子 - 我正在尝试弄清楚如何在单击链接时关闭此下拉菜单,但我的 JavaScript 技能非常缺乏,而且代码似乎很困惑。这是 HTML:
混淆、哈希和加密之间有什么区别? 这是我的理解: 哈希是一种单向算法;无法逆转 混淆与加密类似,但不需要任何“ secret ”即可理解(ROT13 就是一个例子) 加密是可逆的,但需要“ secre
我有以下代码 my $content = $response->content; $content =~ /username=([\s\S]+?)&/; my $username = $1; prin
我在 .NET 中发现了一些与我预期的有点不同的东西。我粘贴的代码没有意义,但它是我拥有的一个复杂得多的函数的浓缩版。我实际上是在获取匿名类型信息作为参数(尚未创建匿名类型的实例),我需要创建该类型的
我正在努力解决 JavaFX 应用程序的混淆问题。使用此项目作为基础: https://github.com/openjfx/samples/tree/master/IDE/IntelliJ/Non-
是否可以制作一个与此类似的 CSV 阅读器 while((line = reader.readLine()) != null){ String[] values = line.
公共(public)类测试2 { 公共(public)静态无效主(字符串[]参数){ System.out.println("3 + 6"); System.out.println(3
我是一名优秀的程序员,十分优秀!