在手册页中,即使您将信号量初始化为值1,也会显示:
sem_init(&mySem, 0, 1);
Run Code Online (Sandbox Code Playgroud)
多次调用时,它仍然可以增加到大于1的值
sem_post(&mySem);
Run Code Online (Sandbox Code Playgroud)
但在这个代码示例中,注释似乎有不同的看法:
sem_init(&mutex, 0, 1); /* initialize mutex to 1 - binary semaphore */
Run Code Online (Sandbox Code Playgroud)
是否可以在C中初始化严格的二进制信号量?
注意:在这种情况下执行此操作而不是使用互斥锁的原因是sem_post和sem_wait可能由不同的线程调用.
我有多个线程访问外部资源 - 一个broswer.但是一次只能有一个线程访问它.所以,我正在使用信号量来同步它们.但是,一个线程从GUI获取输入然后访问浏览器以获得结果,应优先于其他线程,我不知道如何使用信号量来实现它.
我认为获取信号量后的每个线程都会检查队列中是否有优先级线程等待,如果是,则将其释放并再次等待.只有优先级线程在获取后才会释放它.
这是一个很好的解决方案还是我可以使用Java API中的其他任何东西?
我有一个使用sem_wait. 该POSIX规范说:
该
sem_wait()功能可通过信号传送中断。
此外,在关于错误的部分中,它说:
[EINTR] - 一个信号中断了这个功能。
但是,在我的程序中,发送信号不会解除调用的阻塞(并-1按照规范中的指示返回)。
一个最小的例子可以在下面找到。该程序sem_wait在发送信号后挂起并且永远不会解除阻塞。
#include <semaphore.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
sem_t sem;
void sighandler(int sig) {
printf("Inside sighandler\n");
}
void *thread_listen(void *arg) {
signal(SIGUSR1, &sighandler);
printf("sem_wait = %d\n", sem_wait(&sem));
return NULL;
}
int main(void) {
pthread_t thread;
sem_init(&sem, 0, 0);
pthread_create(&thread, NULL, &thread_listen, NULL);
sleep(1);
raise(SIGUSR1);
pthread_join(thread, NULL);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
程序输出Inside sighandler然后挂起。
还有另外一个问题在这里关于这一点,但它并没有真正提供任何清晰。
我误解了规范所说的内容吗?仅供参考,我的电脑使用 Ubuntu GLIBC …
我想使用带有 Gather() 的信号量来限制 api 调用。我想我必须使用 create_task() 但我收到运行时错误:“RuntimeError:await 未与 future 一起使用”。我该如何修复它?
这是代码:
import asyncio
# pip install git+https://github.com/sammchardy/python-binance.git@00dc9a978590e79d4aa02e6c75106a3632990e8d
from binance import AsyncClient
async def catch_up_aggtrades(client, symbols):
tasks = asyncio.create_task(get_historical_aggtrades(client, symbol) for symbol in symbols)
sem = asyncio.Semaphore(1)
async with sem:
await asyncio.gather(*tasks)
async def get_historical_aggtrades(client, symbol):
async for trade in client.aggregate_trade_iter(symbol, '1 day ago UTC'):
print(f"symbol {symbol}")
async def main():
client = await AsyncClient.create()
symbols = ['BTCUSDT', 'ETHUSDT', 'BNBUSDT']
await catch_up_aggtrades(client, symbols)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud) 我有一个包含AFHTTPSessionManager*fileTransferSessionManager的单例类.在其中我有时想要取消所有下载,在重新开始之前,这是通过downloadTasks运行并取消它们.问题是,当调用downloadtasks属性时,如果有正在运行的下载,则主线程会冻结.
// My method canceling download tasks:
NSArray *downloadTasks = self.fileTransferSessionManager.downloadTasks;
for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
[downloadTask cancel];
}
// In AFURLSessionManager.m
- (NSArray *)downloadTasks {
return [self tasksForKeyPath:NSStringFromSelector(_cmd)];
}
Run Code Online (Sandbox Code Playgroud)
调用冻结主线程的方法,因为从不调用带有dispatch_semaphore_signal(信号量)的getTasksWithCompletionHandler:
// In AFURLSessionManager.m
- (NSArray *)tasksForKeyPath:(NSString *)keyPath {
__block NSArray *tasks = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
if ([keyPath isEqualToString:NSStringFromSelector(@selector(dataTasks))]) {
tasks = dataTasks;
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(uploadTasks))]) {
tasks = uploadTasks;
} else if ([keyPath isEqualToString:NSStringFromSelector(@selector(downloadTasks))]) {
tasks …Run Code Online (Sandbox Code Playgroud) 我正在使用信号量来同步我的应用程序中的某些部分.
在释放信号量(sem_release)时,我收到此警告:
sem_release():无法释放密钥0xc:无效的参数
首先我不知道信号量是否被释放,但由于我没有得到"真实"的结果,我猜它不会释放.
PHP版本:5.6.30
ipcs -V =>来自util-linux 2.25.2的ipcs
这是信号量:
key semid owner perms nsems
0x0000000c 4124122 myUser 666 3
Run Code Online (Sandbox Code Playgroud)
这是代码的一部分(类Synchronization):
...
if ( !( $this->semaphoreId = sem_get( $this->id, 1 ) ) )
throw new RuntimeException( 'Error getting Semaphore.');
...
if ( !sem_acquire( $this->semaphoreId ) )
throw new RuntimeException( 'Error acquiring Semaphore.');
...
if ( !sem_release( $this->semaphoreId ) )
throw new RuntimeException( 'Error releasing Semaphore.');
Run Code Online (Sandbox Code Playgroud)
PS我只是在我的生产环境中得到这个错误,而且我无法在我的测试环境中重现/调试.
我在互联网上搜索了这条错误信息,但我一无所获.
有谁知道这个消息是什么意思?
编辑:
我正在尝试创建一个线程安全的属性包装器。我只能认为 GCD 队列和信号量是最快速、最可靠的方式。信号量只是更高的性能(如果这是真的),还是有另一个理由使用一个而不是另一个来实现并发?
以下是原子属性包装器的两种变体:
@propertyWrapper
struct Atomic<Value> {
private var value: Value
private let queue = DispatchQueue(label: "Atomic serial queue")
var wrappedValue: Value {
get { queue.sync { value } }
set { queue.sync { value = newValue } }
}
init(wrappedValue value: Value) {
self.value = value
}
}
@propertyWrapper
struct Atomic2<Value> {
private var value: Value
private var semaphore = DispatchSemaphore(value: 1)
var wrappedValue: Value {
get {
semaphore.wait()
let temp = value
semaphore.signal()
return temp
}
set …Run Code Online (Sandbox Code Playgroud) 我有多个测试文件,每个文件都有一个异步夹具,如下所示:
@pytest.fixture(scope="module")
def event_loop(request):
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest.fixture(scope="module")
async def some_fixture():
return await make_fixture()
Run Code Online (Sandbox Code Playgroud)
我正在使用 xdist 进行并行化。另外我有这个装饰器:
@toolz.curry
def throttle(limit, f):
semaphore = asyncio.Semaphore(limit)
@functools.wraps(f)
async def wrapped(*args, **kwargs):
async with semaphore:
return await f(*args, **kwargs)
return wrapped
Run Code Online (Sandbox Code Playgroud)
我有一个函数使用它:
@throttle(10)
def f():
...
Run Code Online (Sandbox Code Playgroud)
现在f正在从多个测试文件调用,并且我收到一个异常,告诉我无法使用不同事件循环中的信号量。
我尝试转向会话级事件循环装置:
@pytest.fixture(scope="session", autouse=True)
def event_loop(request):
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
Run Code Online (Sandbox Code Playgroud)
但这只给了我:
ScopeMismatch:您尝试使用“模块”范围请求对象访问“函数”范围固定装置“event_loop”,涉及工厂
是否有可能让 xdist + 异步装置 + 信号量一起工作?
我参加聚会迟到了,但我最近了解到SemaphoreSlim:
我曾经用于lock同步锁定,并使用busy布尔值用于异步锁定。现在我SemaphoreSlim什么都用。
private SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
private void DoStuff()
{
semaphoreSlim.Wait();
try
{
DoBlockingStuff();
}
finally
{
semaphoreSlim.Release();
}
}
Run Code Online (Sandbox Code Playgroud)
与
private object locker = new object();
private void DoStuff()
{
lock(locker)
{
DoBlockingStuff();
}
}
Run Code Online (Sandbox Code Playgroud)
是否存在我应该更喜欢使用lockover 的同步情况SemaphoreSlim?如果有,它们是什么?