在研究生班,我们必须使用信号量来完成线程的工作.
我们被指示sem_init与一堆其他sem_*程序一起使用,但我们没有提供关于每个sem_*方法的详细信息.
原型(和头文件)的sem_init是以下:
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
Run Code Online (Sandbox Code Playgroud)
但我不明白pshared值是用来做什么的.根据opengroup.org:
如果
pshared参数具有非零值,则信号量在进程之间共享; 在这种情况下,任何可以访问信号量的进程都sem可以sem用于执行sem_wait(),sem_trywait()和sem_post(),以及sem_destroy()操作.
但我想我不明白说1,2,10,25,50000等之间的区别.我认为如果值为0那么信号量就不会被共享.(但那么,重点是什么?)
如何正确使用此pshared参数?
从Java java.util.concurrent.Semaphore文档中我不太清楚,如果semaphore.acquire()阻塞线程并且之后被InterruptedException中断,会发生什么.信号量值是否已降低,是否需要释放信号量?
目前我使用的代码如下:
try {
// use semaphore to limit number of parallel threads
semaphore.acquire();
doMyWork();
}
finally {
semaphore.release();
}
Run Code Online (Sandbox Code Playgroud)
或者我应该在acquire()期间发生InterruptedException时不要调用release()?
我正在开发一个多线程WindowsPhone8应用程序,它在异步方法中有关键部分.
有没有人知道在C#中正确使用信号量/互斥量的方法,你在使用嵌套的异步调用,其中内部方法可能获取它已经获取了调用堆栈的相同锁?我认为SemaphoreSlim可能是答案,但看起来它会导致死锁.
public class Foo
{
SemaphoreSlim _lock = new SemaphoreSlim(1);
public async Task Bar()
{
await _lock.WaitAsync();
await BarInternal();
_lock.Release();
}
public async Task BarInternal()
{
await _lock.WaitAsync(); // deadlock
// DO work
_lock.Release();
}
}
Run Code Online (Sandbox Code Playgroud) 在上个学期,我在C中学习了OS实习,其中第一个项目涉及制作线程包,然后编写多个生产者 - 消费者程序来演示功能.然而,在获得评分反馈之后,我失去了"信号量的使用是巧妙的错误"和"程序假设抢占(例如使用产量来改变控制)"(我们从一个非抢占式线程包开始然后稍后添加抢占).请注意,注释和示例相互矛盾.我相信它也不会假设,并且可以在两种环境中工作).
这已经困扰了我很长一段时间 - 课程工作人员有点不知所措,所以我不能问他们这个学期有什么问题.我花了很长时间思考这个,我看不出问题.如果有人可以看一看并指出错误,或者向我保证实际上没有问题,我真的很感激.
我相信语法在线程包函数(minithreads和semaphores)方面应该是非常标准的,但是让我知道是否有任何令人困惑的事情.
#include <stdio.h>
#include <stdlib.h>
#include "minithread.h"
#include "synch.h"
#define BUFFER_SIZE 16
#define MAXCOUNT 100
int buffer[BUFFER_SIZE];
int size, head, tail;
int count = 1;
int out = 0;
int toadd = 0;
int toremove = 0;
semaphore_t empty;
semaphore_t full;
semaphore_t count_lock; // Semaphore to keep a lock on the
// global variables for maintaining the counts
/* Method to handle the working of a student
* The ID of a student is …Run Code Online (Sandbox Code Playgroud) 可以在信号量上执行的P()和V()操作是否保证原子?信号量可以阻止两个进程进入P()吗?
包含在<semaphore.h>和中的功能有什么区别<sys/sem.h>?是否存在使用标题或其他更好的情况?
我正在使用信号量,但我一直遇到未定义的参考警告,从而导致我的代码无法工作.我从文本中提取了示例代码,但是他们遇到了一些语法问题,所以我去了POSIX的信号量教程并改变了它们的语法,结果我现在得到了这些引用错误.
我可能只是忽略了一些东西,但我找不到它.
错误:
Producers_Consumers.c:52: warning: return type of ‘main’ is not ‘int’
/tmp/cceeOM6F.o: In function `producer':
Producers_Consumers.c:(.text+0x1e): undefined reference to `sem_init'
Producers_Consumers.c:(.text+0x3a): undefined reference to `sem_init'
Producers_Consumers.c:(.text+0x46): undefined reference to `sem_wait'
Producers_Consumers.c:(.text+0x52): undefined reference to `sem_wait'
Producers_Consumers.c:(.text+0x5e): undefined reference to `sem_post'
Producers_Consumers.c:(.text+0x6a): undefined reference to `sem_post'
/tmp/cceeOM6F.o: In function `consumer':
Producers_Consumers.c:(.text+0x7e): undefined reference to `sem_wait'
Producers_Consumers.c:(.text+0x8a): undefined reference to `sem_wait'
Producers_Consumers.c:(.text+0x96): undefined reference to `sem_post'
Producers_Consumers.c:(.text+0xa2): undefined reference to `sem_post'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
我有什么(由于我从旧方法中评论出来的方式,它可能看起来有点难看)我也知道我的添加方法不起作用,但是当我修复语法问题时我会做到这一点:
#include <stdio.h>
#include …Run Code Online (Sandbox Code Playgroud) 信号量的真正力量是:
限制可以同时访问资源或资源池的线程数
这是明白的.
但是我从来没有机会玩过度Wait接受超时整数的重载,但是 - 这似乎允许多个线程进入临界区,尽管我已经明确设置信号量不允许一次允许多个线程:
private readonly SemaphoreSlim _mutex = new SemaphoreSlim(1);
private void Main()
{
Task.Run(() => DelayAndIncrementAsync());
Task.Run(() => DelayAndIncrementAsync());
}
private void DelayAndIncrementAsync()
{
_mutex.Wait(2000);
try
{
Console.WriteLine(0);
Thread.Sleep(TimeSpan.FromSeconds(5));
Console.WriteLine(1);
}
finally
{
_mutex.Release();
}
}
Run Code Online (Sandbox Code Playgroud)
第一个线程进入互斥区域,打印"0"等待5秒,同时2秒后另一个线程进入临界区?
题
它不是在击败信号量的整个目的吗?
我将使用此超时的真实生活场景是什么,特别是当基本规则是 -
" 信号量 =限制可以同时访问资源或资源池的线程数
对于OS类,我当前必须在linux内核中创建一个线程安全队列,该队列使用系统调用进行交互.
现在对于关键部分,我的直觉是我想要使用标题中的mutex_lock和mutex_unlock函数mutex.h.但是,有人告诉我,我可以改用二进制信号与down_interruptible和up的semaphore.h头,并且它会更好.
我已经阅读了二进制信号量和互斥量之间的区别:从中我了解到,互斥体的主要优点是它强制执行所有权的强度,以及信号量的优势在于,因为它不强制实施所有权,所以您可以使用它作为两个(多个?)不同线程之间的同步机制.
我的问题是二进制信号量的优点是什么,如果你以与互斥量完全相同的方式使用它.如果我写的话更明确:
down()
/* critical */
up()
Run Code Online (Sandbox Code Playgroud)
就像我一样
mutex_lock()
/* critical */
mutex_unlock()
Run Code Online (Sandbox Code Playgroud)
是否有一些性能优势,因为它不如互斥锁安全?我错过了什么吗?
如果你想要更多的上下文(这是我的第一个C proj),这里有一小段我想要线程安全的代码片段:
#define MESSAGE_MAX_SIZE 512
typedef struct list_head list_node;
/* Create message struct */
typedef struct {
size_t size;
list_node node;
char data[MESSAGE_MAX_SIZE];
} Message;
/* Create the linked list queue with dummy head */
struct {
size_t size;
list_node head;
} my_q = { 0, LIST_HEAD_INIT(my_q.head) };
/*
Adds …Run Code Online (Sandbox Code Playgroud) C++20std::atomic有wait和notify_*成员函数,但没有wait_for/ wait_until。
std::atomic使用Microsoft STL 实现WaitOnAddress(当操作系统足够新时)。这个API有一个dwMilliseconds参数,就像超时值一样。因此,从标准库编写者的角度来看,我认为缺少的功能很容易实现(至少在 Windows 8 或更高版本上)。我只是想知道为什么它不在 C++20 中。
但作为(便携式)用户代码编写者,我必须使用标准信号量和原子计数器来模拟行为。所以这是代码:
#include <concepts>
#include <atomic>
#include <type_traits>
#include <cstring>
#include <semaphore>
namespace detail
{
template <size_t N>
struct bytes
{
unsigned char space[N];
auto operator<=>(bytes const &) const = default;
};
//Compare by value representation, as requested by C++20.
//The implementation is a bit awkward.
//Hypothetically `std::atomic<T>::compare(T, T)` would be helpful. :)
template <std::integral T>
bool …Run Code Online (Sandbox Code Playgroud) semaphore ×10
c ×4
c# ×2
concurrency ×2
async-await ×1
atomic ×1
c++ ×1
c++20 ×1
java ×1
linux-kernel ×1
mutex ×1
posix ×1
timeout ×1