标签: semaphore

什么时候调用sem_unlink()?

我对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)

linux semaphore

13
推荐指数
2
解决办法
9731
查看次数

取消SemaphoreSlim.WaitAsync保持信号量锁定

在我们的一个课程中,我们大量使用SemaphoreSlim.WaitAsync(CancellationToken)和取消它.

在调用WaitAsync之后不久取消挂起的调用时,我似乎遇到了问题SemaphoreSlim.Release()(很快,我的意思是在ThreadPool有机会处理排队的项目之前),它将信号量置于没有进一步锁定的状态被收购.

由于的是否非确定性性质ThreadPool项目的通话之间执行以Release()Cancel(),下面的例子并不总是表现出的问题,这种情况下,我已经明确表示要忽略运行.

这是我试图证明问题的例子:

void Main()
{
    for(var i = 0; i < 100000; ++i)
        Task.Run(new Func<Task>(SemaphoreSlimWaitAsyncCancellationBug)).Wait();
}

private static async Task SemaphoreSlimWaitAsyncCancellationBug()
{
    // Only allow one thread at a time
    using (var semaphore = new SemaphoreSlim(1, 1))
    {
        // Block any waits
        semaphore.Wait();

        using(var cts1 = new CancellationTokenSource())
        {
            var wait2 = semaphore.WaitAsync(cts1.Token);
            Debug.Assert(!wait2.IsCompleted, "Should be blocked by the existing wait");

            // Release the …
Run Code Online (Sandbox Code Playgroud)

c# semaphore base-class-library async-await .net-4.5

13
推荐指数
1
解决办法
3980
查看次数

12
推荐指数
2
解决办法
4102
查看次数

Python中命名的信号量?

我在python中有一个脚本,它使用的资源不能超过一定数量的并发脚本运行.

传统上,这可以通过命名信号量来解决,但我无法在多处理模块或线程的文档中找到它们.

我是否遗漏了某些东西,或者是未被Python实现/暴露的命名信号量?更重要的是,如果答案是否定的,那么模仿一个人的最佳方式是什么?

谢谢,波阿斯

PS.由于与此问题不太相关的原因,我无法将任务聚合到持续运行的进程/守护进程或使用生成的进程 - 这两者似乎都适用于python API.

python multithreading semaphore cross-process

12
推荐指数
1
解决办法
5657
查看次数

信号量和同步

我无法从javadocs中的信号量描述中理解以下内容.

请注意,调用acquire()时不会保持同步锁定,因为这会阻止项目返回到池中.信号量封装了限制访问池所需的同步,与维护池本身一致性所需的任何同步分开.

有人可以帮助我理解这个及其含义.

java multithreading semaphore

12
推荐指数
1
解决办法
2477
查看次数

使用Semaphore和gets(int)的Java代码中的死锁

我有以下Java代码:

import java.util.concurrent.*;

class Foo{
    static Semaphore s = new Semaphore(1);

    public void fun(final char c, final int r){
        new Thread(new Runnable(){
            public void run(){
                try{ 
                    s.acquire(r);
                    System.out.println(c+"_"+r);
                    s.release(r+1);
                } catch(Exception e){ e.printStackTrace(); }
            }
        }).start();
    }
}

class ths{
    public static void main(String[]args) throws Exception{
        Foo f = new Foo();
        f.fun('B',2);
        f.fun('F',6);
        f.fun('A',1);
        f.fun('C',3);
        f.fun('D',4);
        f.fun('E',5);
    }
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,这应按顺序打印A_1到F_6并退出,但由于某种原因不会发生.它通常打印A_1和B_2然后卡住.

我的代码找不到任何明显的错误.有什么建议?

java multithreading deadlock semaphore

12
推荐指数
1
解决办法
2824
查看次数

在多个进程之间共享POSIX信号量

我需要创建两个子进程,每个子进程调用execvpater被分叉,可执行文件在它们之间共享POSIX信号量.

我是否需要创建共享内存或仅实现命名信号量?

我从以下链接得到两个答案:

  1. 分叉子进程使用相同的信号量吗?
  2. 如何使用共享内存在进程之间共享信号量

但我对如何继续实施感到困惑.

c posix semaphore ipc

12
推荐指数
1
解决办法
1万
查看次数

sem_open - valgrind抱怨未初始化的字节

我有一个简单的程序:

int main(void)
{
  const char sname[]="xxx";
  sem_t *pSemaphor;
  if ((pSemaphor = sem_open(sname, O_CREAT, 0644, 0)) == SEM_FAILED) {
    perror("semaphore initilization");
    exit(1);
  }
  sem_unlink(sname);
  sem_close(pSemaphor);
}
Run Code Online (Sandbox Code Playgroud)

当我在valgrind下运行它时,我收到以下错误:

==12702== Syscall param write(buf) points to uninitialised byte(s)
==12702==    at 0x4E457A0: __write_nocancel (syscall-template.S:81)
==12702==    by 0x4E446FC: sem_open (sem_open.c:245)
==12702==    by 0x4007D0: main (test.cpp:15)
==12702==  Address 0xfff00023c is on thread 1's stack
==12702==  in frame #1, created by sem_open (sem_open.c:139)
Run Code Online (Sandbox Code Playgroud)

代码是从一个成功运行多年的大型项目中提取的,但现在却导致了分段错误.

我的示例中的valgrind错误与更大的项目中看到的相同,但它会导致崩溃,我的小例子没有.

valgrind semaphore

12
推荐指数
1
解决办法
1008
查看次数

相互排斥和信号量

我正在写一个模拟男女皆宜的浴室的程序(用于家庭作业).一次只允许4个人,如果其他性别已经在使用浴室,男女不能进入.我的问题是允许最多4人在浴室.从输出中可以看出,一次只有一个人进入洗手间.这是我的代码:

const int Delayx = 60;
int i;
int restroom = 0;
int Menwaiting = 0;
int Womenwaiting = 0;
semaphore max_capacity;
semaphore woman;
semaphore man;
semaphore mutex;
semaphore restroomcount;
void Delay(void)
{
    int DelayTime;
    DelayTime = random(Delayx);
    for (i = 0; i<DelayTime; i++);
}

void Woman(void)
{
//  for(;;){
    Womenwaiting++;
    //wait(mutex);
    wait(woman);
    wait(max_capacity);
        //wait(woman);
        wait(mutex);
        wait(restroomcount);
        cout << "A Woman has entered Restroom"<<endl;
        cout << "People in the Restroom:" << restroom++ <<endl <<endl;
        signal(restroomcount);
        Womenwaiting--;
        Delay();
        wait(restroomcount);
        cout << …
Run Code Online (Sandbox Code Playgroud)

c++ mutex semaphore

11
推荐指数
1
解决办法
9350
查看次数

为什么PHP的sem_acquire会阻止程序执行?

我正在研究一个在gentoo Linux上运行的非常大而复杂的PHP项目,这显然存在PHP信号量的一些问题.由于项目的规模和复杂性,我无法发布代码.我也无法提供再现问题的工作示例.它可能是由程序的复杂性以非威慑方式引起的.

问题出在这里:PHP代码正在尝试使用信号量写入和读取共享内存.在产生问题的情况下,执行以下操作:

  1. 在时间006.68,PHP 4.4.9执行以下代码,将5个字节的数据写入共享内存,$iVarKey其值为2010147023

    sem_acquire($this->rSemaphore);
    shm_put_var($this->rShm, $iVarKey, $mVar);
    sem_release($this->rSemaphore);
    
    Run Code Online (Sandbox Code Playgroud)

    此操作在006.69时结束

  2. 在时间006.77,PHP 5.2.10执行以下代码,从共享内存中读取5个字节的数据,$iVarKey其值为622679600:

    sem_acquire($this->rSemaphore);
    $mVar = shm_get_var($this->rShm,$iVarKey);
    sem_release($this->rSemaphore);
    
    Run Code Online (Sandbox Code Playgroud)

    此操作在006.78时结束

  3. 在时间016.01以下代码是由PHP 5.2.10(的代码相同的行中#2)执行,以从共享存储器读出5个字节的数据,以$iVarKey具有值2010147023(同#1):

    sem_acquire($this->rSemaphore);
    $mVar = shm_get_var($this->rShm,$iVarKey);
    sem_release($this->rSemaphore);
    
    Run Code Online (Sandbox Code Playgroud)

    此操作现在大约需要2分钟,尽管具有相同的资源/信号量$iVarKey已提前约10秒发布.在此期间没有访问共享内存,因为我已经确定了每次调用sem_acquire!

如何sem_acquire阻止程序执行,尽管它不应该.也许这是版本4.4.9/5.2.10中的错误?有没有人看起来像类似的东西?有解决方法吗?我可以做些什么来进一步投资这个问题吗?

我真的很感激这个问题的帮助!

备注:

  • 如果您需要其他信息,我会尝试提供
  • 请不要评论和评论PHP4或并行使用两个PHP版本.
  • 如果人们认为这个问题不属于此,请提供指导.

附加信息: - 我已经检查过每次通话sem_release,但似乎没有人回复FALSE.因此,我的问题并非来自失败的释放.- 当系统阻塞时,ipcs -s返回以下输出,与系统未阻塞时相同

    ------ Semaphore Arrays --------
    key        semid      owner      perms      nsems     
    0x000f4240 0          root      666        3         
    0x00000001 32769      root      666        3         
    0x00000000 65538      apache    600 …
Run Code Online (Sandbox Code Playgroud)

php semaphore shared-memory

11
推荐指数
1
解决办法
1389
查看次数