- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一些代码在其中使用 dispatch_semaphore_t 来指示操作完成。当信号量是成员变量时,它的行为似乎不正确。我将展示有效的示例代码和一个似乎无效的示例:
@implementation someClass
{
dispatch_semaphore_t memberSem;
dispatch_semaphore_t* semPtr;
NSThread* worker;
BOOL taskDone;
}
- (id)init
{
// Set up the worker thread and launch it - not shown here.
memberSem= dispatch_semaphore_create(0);
semPtr= NULL;
taskDone= FALSE;
}
- (void)dealloc
{
// Clean up the worker thread as needed - not shown here.
if((NULL != semPtr) && (NULL != *semPtr))
disptatch_release(*semPtr);
dispatch_release(memberSem);
}
- (void)doSomethingArduous
{
while([self notDone]) // Does something like check a limit.
[self doIt]; // Does something like process data and increment a counter.
taskDone= TRUE; // I know this should be protected, but keeping the example simple for now.
if((NULL != semPtr) && (NULL != *semPtr))
dispatch_semaphore_signal(*semPtr); // I will put a breakpoint here, call it "SIGNAL"
}
- (BOOL)getSomethingDoneUseLocalSemaphore
{
taskDone= FALSE; // I know this should be protected, but keeping the example simple for now.
dispatch_semaphore_t localSem= dispatch_semaphore_create(0);
semPtr= &localSem;
[self performSelector:doSomethingArduous onThread:worker withObject:nil waitUntilDone:NO];
dispatch_time_t timeUp= dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(2.5 * NSEC_PER_SEC));
dispatch_semaphore_wait(localSem, timeUp);
semPtr= NULL;
dispatch_release(localSem);
// I know I could just return taskDone. The example is this way to show what the problem is.
if(taskDone) // Again with thread safety.
return TRUE;
return FALSE;
}
- (BOOL)getSomethingDoneUseMemberSemaphore
{
taskDone= FALSE; // I know this should be protected, but keeping the example simple for now.
semPtr= &memberSem; // I will put a breakpoint here, call it "START"
[self performSelector:doSomethingArduous onThread:worker withObject:nil waitUntilDone:NO];
dispatch_time_t timeUp= dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(2.5 * NSEC_PER_SEC));
dispatch_semaphore_wait(memberSem, timeUp);
semPtr= NULL;
// I know I could just return taskDone. The example is this way to show what the problem is.
if(taskDone) // Again with thread safety.
return TRUE; // I will put a breakpoint here, call it "TASK_DONE"
return FALSE; // I will put a breakpoint here, call it "TASK_NOT_DONE"
}
- (void)hereIsWhereWeBringItTogether
{
BOOL gotItDoneLocal= [self getSomethingDoneUseLocalSemaphore]; // Will return TRUE.
gotItDoneLocal= [self getSomethingDoneUseLocalSemaphore]; // Will return TRUE.
gotItDoneLocal= [self getSomethingDoneUseLocalSemaphore]; // Will return TRUE.
BOOL gotItDoneMember= [self getSomethingDoneUseMemberSemaphore]; // Will return TRUE. I will put a breakpoint here, call it "RUN_TEST"
gotItDoneMember= [self getSomethingDoneUseMemberSemaphore]; // Will return FALSE.
}
因此,鉴于该代码和我得到/得到的结果,我按照我的真实代码中的描述放置了断点:一个在主函数中,一个在工作函数中开始,一个在成员信号量发出信号的地方,以及等待后两个。
我发现在我使用成员信号量的情况下,在第一轮我停在断点“RUN_TEST”,运行并命中断点“START”,运行然后命中断点“SIGNAL”,运行然后命中断点“TASK_DONE”——一切如预期。
当我继续运行时,我遇到断点“START”,运行然后遇到断点“TASK_NOT_DONE”,运行然后遇到断点“SIGNAL”
也就是说,当我使用作为成员的信号量运行序列,并执行看起来正确的信号/等待时,我第二次尝试等待那个信号量时,我似乎错过了它,它在我发出信号后收到信号已经退出等待。
我似乎要么没有管理计数权(信号/等待配对),要么该成员信号量不会返回到未发出信号的状态。
我觉得这里缺少一些基本的东西。任何输入将不胜感激。
编辑:最终我似乎遗漏了什么是因为我的实际代码有点复杂。不是从艰巨的任务中干净利落地返回,而是涉及多个线程和一个 postNotification。我用通知处理程序中的代码替换了 postNotification - 它设置了一个标志并向信号量发出信号。这样就消除了通知处理程序可能引入的任何延迟。
最佳答案
是的,这是预期的行为。如果您等待信号超时,当信号到来时,next 调用 dispatch_semaphore_wait
将捕获该信号量。考虑以下示例:
例如:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_time_t timeout;
// in 5 seconds, issue signal
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(5);
NSLog(@"Signal 1");
dispatch_semaphore_signal(semaphore);
});
// wait four seconds for signal (i.e. we're going to time out before the signal)
NSLog(@"Waiting 1");
timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC));
if (dispatch_semaphore_wait(semaphore, timeout))
NSLog(@"Waiting for 1: timed out");
else
NSLog(@"Waiting for 1: caught signal");
// now, let's issue a second signal in another five seconds
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(5);
NSLog(@"Signal 2");
dispatch_semaphore_signal(semaphore);
});
// wait another four seconds for signal
// this time we're not going to time out waiting for the second signal,
// because we'll actually catch that first signal, "signal 1")
NSLog(@"Waiting 2");
timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC));
if (dispatch_semaphore_wait(semaphore, timeout))
NSLog(@"Waiting for 2: timed out");
else
NSLog(@"Waiting for 2: caught signal");
// note, "signal 2" is still forthcoming and the above code's
// signals and waits are unbalanced
因此,当您使用类实例变量时,您的 getSomethingDoneUseMemberSemaphore
的行为与上面类似,其中对 dispatch_semaphore_wait
的第二次调用将捕获发出的第一个信号,因为 (a) 它是同一个信号量; (b) 如果第一次调用 dispatch_semaphore_signal
超时。
但是如果你每次都使用唯一的信号量,那么第二次调用dispatch_semaphore_wait
将不会响应第一个信号量的dispatch_semaphore_signal
。
关于objective-c - dispatch_semaphore_t 重用-我在这里缺少什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18363936/
我正在尝试在 map 上绘制一些疾病事件数据的位置。 我用它来导入数据: ByTown% addProviderTiles("CartoDB.Positron")%>% addPolygons
我有一个文件调用 find.js,我使用 node find.js 运行,我的节点是版本 10 我不知道为什么我无法使用 async await。 const axios = require("axi
我有一个项目作为引用添加到 System.Web。 但是,它似乎无法获取 HttpContext。这样做: Imports System.Web _ApplicationBase = HttpCont
在互联网上找到这段代码,出于某种原因它缺少 while 循环逻辑“while(i....)”,虽然我找到了 PigLatin* 问题的其他可行解决方案,但我真的很想了解这个正在工作。 *PigLati
我工作了一整天来运行 Xampp 并在其上安装 TYPO3。现在我登录到后端,但没有显示许多管理模块,例如模板、访问等。 - 一定是我做错了什么,但我不知道。 these are the module
你好 我有编译这个问题 \begin{equation} J = \sum_{j=1}^{C} \end{equation} 我不断收到错误 missing $ inserted 这很奇怪,因
我正在尝试使用 SQLite CLI,但无法获得 generate_series功能来工作。我可以按照文档中的建议使用递归 CTE 对其进行模拟,但我似乎无法获得该链接中的任何示例。这是我的 sess
我目前正在开发我想要的软件,而软件正在安装,它可以在后台为软件创建 native 图像。 我正在考虑使用 NGEN 并将进程优先级设置为低,因为我不希望它消耗 100% CPU。但是我发现我的计算机上
我想使用 Xcodes Instruments 进行 UI 自动化测试。但似乎缺少“自动化”。我怎样才能添加这个? 最佳答案 如果您想使用自动化仪器,请使用 Xcode 7.3。 Apple 在 Xc
我目前在 JS 开发中迈出了一小步,并编写了以下链接添加器: const button = document.getElementById('button') const listdiv = docu
此代码有什么问题: NSError *error = nil; [SFHFKeychainUtils deleteItemForUsername:@"IAPNoob01" andServiceName
出于某种原因,在安装和配置(我认为)一切之后,com.adobe.utils.AGALMiniAssembler 不见了,其他一切正常。 我认为我已尽一切努力让孵化器正常工作,但显然我错过了一步。 如
我有一个名为 new 的方法。调用 new 时,我传递了一个参数,但是当我运行应用程序时,出现没有参数或参数为空的错误。 StepReader.pm package StepReader; use s
安装 gtk 1.2(包名 gtk1)和 macports chokes 在最终的 make 中,在 libintl.h 的第 440 行。 extern locale_t libintl_newlo
我用按钮创建表格。 这是javascript代码: function layersListTable(layers) { var content =''; $.each($(layer
我在使用此 javascript 时遇到此错误,任何人都可以帮我弄清楚我做错了什么吗? $(this).prepend('Check availability »'); 它给我错误 mis
我有一个独立的工具链 NDK13b、api19、llvm 3.8 编译器、arm 32 位、带有 libcpp(llvm C++ 库) 我想避免依赖 libgcc,所以我构建了 compiler-rt
我按照一些教程使用 phonegap 的条形码扫描器插件。但是当我从现有源创建一个新的 android 项目来创建条码库时 (step 6 in this page)我收到错误:“AndroidMan
我现在尝试在 Eclipse 中打开我的布局 xml 文件。我只得到错误 No XML content. Please add a root view or layout to your docume
我的 android-sdk-windows\tools 目录中缺少层次结构查看器工具。 工具链接: http://developer.android.com/guide/developing/too
我是一名优秀的程序员,十分优秀!