信号量可以低于0吗?我的意思是,说我有一个N = 3的信号量,我称之为"向下"4次,然后N将保持为0,但是一个进程将被阻止?
而另一方面,如果在一开始我打电话,N可以高于3吗?因为正如我所看到的那样,如果在开始时N可以高于3,我会调用几次,然后我可以调用更多次,因此在关键部分放入更多进程然后信号量允许我.
如果有人为我澄清一点,我会非常感激.
格雷格
我想知道使用POSIX调用pthread_once()和/ sem_wait()或dispatch_*函数会更好/更快,所以我创建了一个小测试并对结果感到惊讶(问题和结果在最后).
在测试代码中,我使用mach_absolute_time()来为调用计时.我真的不在乎这与纳秒没有完全匹配; 我正在将这些值相互比较,因此确切的时间单位无关紧要,只有间隔之间的差异.结果部分中的数字是可重复的而不是平均数; 我可以平均时间,但我不是在寻找确切的数字.
test.m(简单的控制台应用程序;易于编译):
#import <Foundation/Foundation.h>
#import <dispatch/dispatch.h>
#include <semaphore.h>
#include <pthread.h>
#include <time.h>
#include <mach/mach_time.h>
// *sigh* OSX does not have pthread_barrier (you can ignore the pthread_barrier
// code, the interesting stuff is lower)
typedef int pthread_barrierattr_t;
typedef struct
{
pthread_mutex_t mutex;
pthread_cond_t cond;
int count;
int tripCount;
} pthread_barrier_t;
int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
{
if(count == 0)
{
errno = EINVAL;
return -1;
}
if(pthread_mutex_init(&barrier->mutex, 0) < 0) …Run Code Online (Sandbox Code Playgroud) 几个星期前我开始用Python编程,并试图使用Semaphores同步两个简单的线程,用于学习目的.这是我得到的:
import threading
sem = threading.Semaphore()
def fun1():
while True:
sem.acquire()
print(1)
sem.release()
def fun2():
while True:
sem.acquire()
print(2)
sem.release()
t = threading.Thread(target = fun1)
t.start()
t2 = threading.Thread(target = fun2)
t2.start()
Run Code Online (Sandbox Code Playgroud)
但它一直打印只有1.如何对照片进行内部缩放?
我已经阅读了SemaphoreSlim SemaphoreSlim MSDN的文档, 它表明SemaphoreSlim会限制一段代码,如果你将它配置为一次只能由一个线程运行:
SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
Run Code Online (Sandbox Code Playgroud)
但是,它不表示它是否阻止相同的线程访问该代码.这提出了异步和等待.如果在方法中使用await,则控制将离开该方法,并在任何任务或线程完成时返回.在我的示例中,我使用了一个带有异步按钮处理程序的按钮.它使用'await'调用另一个方法(Function1).Function1依次调用
await Task.Run(() => Function2(beginCounter));
Run Code Online (Sandbox Code Playgroud)
在我的Task.Run()周围,我有一个SemaphoreSlim.肯定看起来它会阻止同一个线程进入Function2.但是这并不能保证(正如我读到的那样)来自文档,我想知道是否可以依靠它.
我在下面发布了完整的例子.
谢谢,
戴夫
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace AsynchAwaitExample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
public MainWindow()
{
InitializeComponent();
}
static int beginCounter = 0;
static int endCounter = 0;
/// <summary>
/// Suggest hitting button 3 times …Run Code Online (Sandbox Code Playgroud) 所以我收到错误:"对sem_open()的未定义引用",即使我已经包含了semaphore.h头文件.我的所有pthread函数调用(mutex,pthread_create等)都发生了同样的事情.有什么想法吗?我使用以下命令编译:
g ++'/ home/rbin /Desktop/main.cpp'-o'/ home/robin /Desktop/main.out'
#include <iostream>
using namespace std;
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
const char *serverControl = "/serverControl";
sem_t* semID;
int main ( int argc, char *argv[] )
{
//create semaphore used to control servers
semID = sem_open(serverControl,O_CREAT,O_RDWR,0);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在开发一个MATLAB项目,我希望有两个并行运行的MATLAB实例并共享数据.我会打电话给这些实例MAT_1和MAT_2.更具体地说,该系统的架构是:
MAT_1按顺序处理图像,逐个读取它们imread,并使用输出每个图像的结果imwrite.MAT_2通过MAT_1使用读取输出的图像,imread并将其结果输出到其他地方.我认为我需要解决的一个问题是保证一次MAT_2读取图像输出完全写入它.MAT_1MAT_1
我的问题是:
flock,但由MATLAB直接提供,并且可在多个平台上运行,例如Windows和Linux).如果没有,您是否知道我可以使用任何第三方库在MATLAB中构建此机制?为什么我需要MAT_1和MAT_2并行线程中运行?:
完成的处理MAT_2平均较慢(并且更容易崩溃)MAT_1,并且MAT_1其他程序和进程(包括人工检查)的输出不需要等待MAT_2完成其工作.
我需要两个线程以"tick tock"模式进行.当使用信号量实现时,这看起来很好:
Semaphore tick_sem(1);
Semaphore tock_sem(0);
void ticker( void )
{
while( true )
{
P( tick_sem );
do_tick();
V( tock_sem );
}
}
void tocker( void )
{
while( true )
{
P( tock_sem );
do_tock();
V( tick_sem );
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用互斥锁(在技术上是一个二进制信号量)做同样的事情,它有一个奇怪的代码气味.
std::mutex tick_mutex;
std::mutex tock_mutex;
tock_mutex.lock();
void ticker( void )
{
while( true )
{
tick_mutex.lock();
do_tick();
tock_mutex.unlock();
}
}
void tocker( void )
{
while( true )
{
tock_mutex.lock()
do_tock();
tick_mutex.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为气味是互斥不是为了将信息传达给另一个线程.(c ++ …
如果它保证满足以下所有条件,我需要检查解决餐饮哲学家问题的算法:
我在筷子上使用信号量来解决问题.
这是我的代码(算法):
while(true)
{
// He is Hungry
pickup_chopsticks(i);
// He is Eating...
drop_chopsticks(i);
// He is thinking
}
// ...
void pickup_chopsticks(int i)
{
if(i % 2 == 0) /* Even number: Left, then right */
{
semaphore_wait(chopstick[(i+1) % NUM_PHILOSOPHERS]);
semaphore_wait(chopstick[i]);
}
else /* Odd number: Right, then left */
{
semaphore_wait(chopstick[i]);
semaphore_wait(chopstick[(i+1) % NUM_PHILOSOPHERS]);
}
}
void drop_chopsticks(int i)
{
semaphore_signal(chopstick[i]);
semaphore_signal(chopstick[(i+1) % NUM_PHILOSOPHERS]);
}
Run Code Online (Sandbox Code Playgroud)
我相信这里不存在死锁的可能,但这里有可能出现饥饿问题吗?如果是,我该如何解决?
我对Linux API sem_unlink()感到有些困惑,主要是在何时或为何调用它.我在Windows中使用了多年的信号量.在Windows中,一旦关闭了命名信号量的最后一个句柄,系统就会删除底层内核对象.但是在Linux中,开发人员需要通过调用sem_unlink()来删除内核对象.如果不这样做,内核对象将保留在/ dev/shm文件夹中.
我遇到的问题是,如果进程A调用sem_unlink()而进程B锁定了信号量,它会立即销毁信号量,当进程C出现时,进程B不再被信号量"保护".更重要的是,手册页充其量令人困惑:
"信号量名称立即被删除.一旦所有其他具有信号量打开的进程关闭它,信号量就会被破坏."
如果它必须等待其他进程关闭信号量,它如何立即销毁对象?
显然,我不明白在Linux上正确使用信号量对象.谢谢你的帮助.下面是我用来测试它的一些示例代码.
int main(void)
{
sem_t *pSemaphore = sem_open("/MyName", O_CREAT, S_IRUSR | S_IWUSR, 1);
if(pSemaphore != SEM_FAILED)
{
if(sem_wait(pSemaphore) == 0)
{
// Perform "protected" operations here
sem_post(pSemaphore);
}
sem_close(pSemaphore);
sem_unlink("/MyName");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) semaphore ×10
c++ ×2
linux ×2
mutex ×2
.net ×1
algorithm ×1
async-await ×1
c ×1
c# ×1
c++11 ×1
concurrency ×1
java ×1
matlab ×1
objective-c ×1
pthreads ×1
python ×1
reentrancy ×1