我面临pthread的同步问题。threadWaitFunction1,是线程等待函数。我希望行号。flag = 1
仅在243-246完成后才执行247
。但我感到奇怪的是,有时它会在243-246完成之前直接跳到247。
请帮我。
提前致谢。
236 struct timespec timeToWait;
237 static void* threadWaitFunction1(void *timeToWaitPtr)
238 {
239 cout << "Setting flag =0 inside threadWaitFunction1\n";
240
241 cout << "Inside threadWaitFunction\n";
242 struct timespec *ptr = (struct timespec*) timeToWaitPtr;
243 pthread_mutex_lock(&timerMutex);
flag = 0;
244 pthread_cond_timedwait(&timerCond, &timerMutex, ptr);
flag=1;
245 pthread_mutex_unlock(&timerMutex);
246 cout << "Setting flag =1 inside threadWaitFunction1\n";
247
248
249 }
创建并调用上述线程的线程是:
263 static void timer_trackStartTime ()
264 {
265 struct timeval now;
266 pthread_t thread;
267
268 printf("Inside trackStartTime: flag = %d\n",flag);
269
270 /* Setting timer expiration */
271 timeToWait.tv_sec = lt_leak_start_sec;; // First expiry after 1 sec
272 timeToWait.tv_nsec = lt_leak_start_nsec;
273 pthread_create(&thread, NULL, threadWaitFunction1, &timeToWait);
274 pthread_join(thread, NULL);
275 //pthread_kill(thread, SIGKILL); // Destroying the thread to ensure no leaks
276
.
.
283 }
如果我使用pthread_mutex_lock保护整个函数,但仍然存在相同的问题。 如何确保有序执行?有人可以帮忙吗?
编辑:now.tv_sec和now.tv_nsec从代码中删除。 * 编辑:更改了互斥锁内的标志(仍然不起作用) *
因此,真正使执行不满意的不是真正的执行顺序(这很可能是正确的)。在“它在243-246完成之前直接跳到247”下的意思是“我观察到它在应在244中等待的时间过去之前执行了247”。对?
然后,我怀疑这是虚假唤醒的问题:即使没有其他线程发出条件变量的信号,一个线程也可能被唤醒。的规范pthread_cond_timedwait()
说:“可能会发生从pthread_cond_timedwait()或pthread_cond_wait()函数的虚假唤醒。”
通常,条件变量与应用程序中的某个事件相关联,实际上,等待条件变量的线程会等待另一个线程发出的信号,表明相关事件已经发生。如果您没有事件,只是想等待一定的时间,那么实际上其他方法(例如usleep()
或timers)更合适,除非您还需要pthread取消点。
补充:由于您似乎很满意,usleep()
并且仅询问为什么pthread_cond_timedwait()
不符合您的期望,所以我决定不发布代码。如果需要,可以使用@Hasturkun的答案。
ADDED-2:以下注释中的输出(在应用Hasturkun解决方案之后获得)表明等待线程没有退出循环,这可能意味着pthread_cond_timedwait()
返回的内容与ETIMEDOUT不同。您是否看到过@nos对您的帖子的评论(我固定了要减去的纳秒数):
确保(now.tv_usec * 1000)+ lt_leak_start_nsec;
不会溢出。您只能将tv_nsec设置为最大999999999,如果表达式大于该值,则应从tv_nsec减去1000000000,然后将tv_sec递增1。如果您的timeToWaitPtr包含无效的tv_nsec(大于999999999),则pthread_cond_timedwait将失败(您应检查其返回值也是如此。)–否Apr
4月28日19:04
在这种情况下,pthread_cond_timedwait()
将反复返回EINVAL
并且永远不会退出循环。最好在进入等待循环之前调整超时,尽管也可以响应来完成EINVAL
。
ADDED-3:现在,在您更改问题中的代码以通过超时而不增加当前时间后,它又出现了另一个问题。如规范中所述,超时pthread_cond_timedwait()
是绝对时间,不是相对时间;因此,如果您将超时时间设置为3秒,则将其解释为“自系统时间参考点起3秒”。几乎可以肯定,这一刻已经过去了一段时间,因此pthread_cond_timedwait()
立即返回。
我建议您通读规范(包括基本原理),以更好地了解应该如何使用此功能。
我在Java写程序,有点担心同步。 这个场景非常“简单”,我们有一个简单的银行账户类,多人可以从账户中取款(虽然他们不能存款),他们也可以检查账户余额。问题是,余额一直在变化,因此我们希望客户查看正确的余额! 到目前为止,这是我的班级。 正如您可以看到的,通过这个实现,我可以确保有人可以从一个account对象获得资金,但是这个account对象被阻止了,然后一个解决方案出现了 添加这似乎解决了我
我安装了Android Studio 3.4,在同步gradle时遇到了这个问题。我到处都找不到解决问题的办法。 以下是我收到的错误: “无法解析:com.android。支持:appcompat-v7:28.0.0在项目结构对话框中显示受影响的模块:app” “无法解析:com.android.support。约束:约束布局:1.1.3在项目结构对话框中显示受影响的模块:应用程序” “无法解析:
问题内容: SimpleDateFormat的Javadoc指出SimpleDateFormat没有同步。 “日期格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一种格式,则必须在外部进行同步。” 但是,在多线程环境中使用SimpleDateFormat实例的最佳方法是什么。这是我想到的一些选项,我过去曾使用过选项1和2,但是我很想知道是否有更好的选择,或者这些选项中的哪一个可以
线程2:4 . . 线程3:7 线程3:8 线程1:9 这是我为正在执行线程的类编写的代码 我认为问题在于NumberEntry对象的创建。但我不太确定怎么修好它。如果有人能以任何方式帮助我,那就太好了:)。
互斥锁 互斥锁的本质是当一个 goroutine 访问的时候,其它 goroutine 都不能访问 这样就能实现资源同步,但是在避免资源竞争的同时也降低了程序的并发性能,程序由原来的并发执行变成了串行 案例 有一个打印函数, 用于逐个打印字符串中的字符,有两个人都开启了goroutine去打印 如果没有添加互斥锁,那么两个人都有机会输出自己的内容 如果添加了互斥锁,那么会先输出某一个的,输出完毕之
为什么下面的代码不能保证多个线程之间total_home数字的唯一性,即使逻辑处于同步块中。 } } } 这是一个程序示例。试着运行5-10次,你会发现total_home的值并不是每次都是唯一的。