我正在将Windows应用程序移植到Linux,我遇到了同步问题.
在Windows中,我使用系统级别的名为mutex来同步对共享内存块的访问.
我如何在Linux中模拟它?我使用semget创建了一个SystemV信号量.问题是它不是可重入的,如果我已经持有它会阻塞,不像在Windows上.我可以为它添加一个引用计数,但是我需要同步访问它,这意味着另一个(这次只适用于当前进程)互斥.
是否有某个类提供了可重入的进程间锁(可能在Boost中)?
顺便说一句,使用文件锁是不可接受的,因为它可能太慢(我需要在两个进程之间进行超低延迟通信).
我使用SysV共享内存让两个进程相互通信。我不希望代码变得复杂,所以我想知道是否真的需要使用信号量来同步对共享内存的访问。在我的C / C ++程序中,父进程从共享内存中读取,子进程写入共享内存中。我编写了两个测试应用程序,以查看是否会产生诸如分段错误之类的错误,但我无法(Ubuntu 10.04 64bit)。即使两个进程在while循环中不停地写入同一共享内存也不会产生任何错误。
我希望有人对此事有经验,可以告诉我是否真的必须使用信号量来同步访问,或者我是否可以不进行同步。
谢谢
我会在共享内存中保留一些数据,使用命名信号量来管理访问:
#include <boost/interprocess/sync/named_semaphore.hpp>
struct shared_memory_buffer
{
// Application data
int items[10];
// Synchronization data
boost::interprocess::named_semaphore syncSem;
shared_memory_buffer()
: syncSem(boost::interprocess::open_or_create_t, "testSemaphore", 0) // error
{}
};
Run Code Online (Sandbox Code Playgroud)
但是,我在指定的行得到以下编译时错误:
error: expected primary-expression before ‘,’ token
Run Code Online (Sandbox Code Playgroud)
这是我的系统:
MacOS X 10.6
i686-apple-darwin10-g ++ - 4.2.1(GCC)4.2.1(Apple Inc. build 5664)
提升1.44
谢谢!
换句话说,我不希望线程等待它无法访问锁(如在同步中),我想线程执行只是在它无法获得锁时立即返回.
像这样简单的布尔锁可能允许多个线程访问.
private static boolean lockAvailable = true;
private boolean acquireLock() {
if(lockAvailable) {
lockAvailable = false;
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?实现这一目标的最佳/最简单方法是什么?
编辑:
谢谢你指出信号量(!)
所以再看一遍这段代码是防弹吗?
private final static Semaphore lock = new Semaphore(1, true);
public void tryAndDoSomething() {
if(lock.tryAcquire()) {
try {
// only single thread can access here at one time
} finally {
lock.release();
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
我意识到我需要可重入的功能,所以我创建了一个简单的非阻塞重入.为任何对您如何执行此操作感兴趣的人发布代码.任何想要这种功能的人当然应该使用现有的 Java类java.util.concurrent.locks.ReentrantLock:
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
* SimpleNonBlockingLock ensures that only a single thread can call …Run Code Online (Sandbox Code Playgroud) 所以,我正在我的一个班级中安排一个调度程序.基本上,我们假装一次只能执行一个线程.我们应该使用信号量类来允许这些线程阻塞自己来模拟等待CPU的线程.
问题是,线程似乎在错误的时间阻塞并在错误的时间执行.我想知道我是否缺少对信号量的概念性理解以及如何实现它.我想知道我是否能对我的实施得到一些反馈.教师提供了这个头文件,我没有以任何方式修改过:
class Semaphore {
private:
int value;
pthread_mutex_t m;
pthread_cond_t c;
public:
/* -- CONSTRUCTOR/DESTRUCTOR */
Semaphore(int _val);
//~Semaphore();
/* -- SEMAPHORE OPERATIONS */
int P();
int V();
};
Run Code Online (Sandbox Code Playgroud)
这是我使用posix东西的实现:
Semaphore::Semaphore(int _val){
value = _val;
c = PTHREAD_COND_INITIALIZER;
m = PTHREAD_MUTEX_INITIALIZER;
}
int Semaphore::P(){
if(value <= 0){
pthread_cond_wait(&c, &m);
}
value--;
}
int Semaphore::V(){
value++;
if(value > 0){
pthread_cond_signal(&c);
}
}
Run Code Online (Sandbox Code Playgroud) 我无法调试以下程序,因为我家里没有linux.我无法执行该程序,但在实验室会话中编译程序时,我遇到了两个错误.谁能帮我吗?如果有人能够在调试后执行该程序,请发布输出.
代码如下:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
int buffer[BUFFER_SIZE];
pthread_t ptid,ctid;
pthread_attr_t attr;
void *producer(void *param);
void *consumer(void *param);
int counter;
int main()
{
init();
pthread_create(&ptid, &attr, producer, NULL);
pthread_create(&ctid, &attr, consumer, NULL);
pthread_join(ptid,NULL);
pthread_join(ctid,NULL);
return 0;
}
void init()
{
pthread_mutex_init(&mutex, NULL);
pthread_attr_init(&attr);
sem_init(&full, 0, 0);
sem_init(&empty, 0, BUFFER_SIZE);
counter = 0;
for(int j=0;j<BUFFER_SIZE;j++)
{ buffer[j] = 0;}
}
void *producer(void *param)
{
int item;
while(1)
{ …Run Code Online (Sandbox Code Playgroud) 我有这个类,这是文件锁定实用程序的基本方法(不与OS的锁相互作用).我们的想法是拥有一个静态HashMap,它存储对应用程序使用二进制信号量的File对象的一对引用.首次访问新文件时,该对存储在变量中.问题是,.wait()行抛出抛出:IllegalMonitorStateException,我不明白为什么,因为我已经创建了一个项目来测试这个类只有一个线程,所以这是不可能的线程访问方法不拥有对象,不是吗?
public abstract class FileLocker {
private static final HashMap<File, Semaphore> locksMap = new HashMap<>();
public synchronized static final void getLock(final File file) {
if (!FileLocker.locksMap.containsKey(file)) {
FileLocker.locksMap.put(file, new Semaphore(1, Boolean.TRUE));
}
try {
FileLocker.locksMap.get(file).wait();
} catch (final InterruptedException e) {
SysLogger.log(e, "ERR0", SysLogger.Level.CRASH);
}
if (file.isDirectory()) {
for (final File f : file.listFiles()) {
if (f.isDirectory()) {
FileLocker.getLock(f);
}
}
}
}
public synchronized static final void releaseLock(final File file) {
if (file.isDirectory()) {
for (final File f : …Run Code Online (Sandbox Code Playgroud) 我需要使用信号量并行完成一些任务.我试试这个:
Semaphore sema = new Semaphore(2,2);
Thread[] Threads = new Thread[5];
for (int k = 0; k < 5; k++) {
sema.WaitOne();
Console.WriteLine((k + 1) + " started");
Threads[k] = new Thread(ThreadMethod1);
Threads[k].Start(k + 1);
sema.Release();
}
static void ThreadMethod1(object id) {
Thread.Sleep(50);
Console.WriteLine(id + " completed");
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
1 started
2 started
3 started
4 started
5 started
1 completed
2 completed
4 completed
3 completed
5 completed
Run Code Online (Sandbox Code Playgroud)
是不是信号量应该让只有2个线程运行?我不明白或做错了什么?
我在一个开始的线程上遇到了一些代码
open (S, $SEMAPHORE) or die;
我不熟悉用作裸字的S. 它指的是什么?以前没有使用更高的代码示例.
我正在设计一个.net核心Web API,它使用了我无法控制的外部API。我在堆栈溢出中找到了一些极好的答案,这些问题使我可以在使用semaphoreslim的同一线程中限制对此外部API的请求。我想知道如何最好地将这种限制扩展到整个应用程序,而不仅仅是限制特定任务列表。我一直在学习HttpMessageHandlers,这似乎是拦截所有传出消息并应用限制的一种可能方法。但是我担心线程安全性和锁定问题,我可能不了解。我包括了当前的限制代码,希望对理解我正在尝试做的事情有所帮助,但是要跨越多个线程,并且不断添加任务而不是预先定义的任务列表。
private static async Task<List<iMISPagedResultResponse>> GetAsyncThrottled(List<int> pages, int throttle, IiMISClient client, string url, int limit)
{
var rtn = new List<PagedResultResponse>();
var allTasks = new List<Task>();
var throttler = new SemaphoreSlim(initialCount: throttle);
foreach (var page in pages)
{
await throttler.WaitAsync();
allTasks.Add(
Task.Run(async () =>
{
try
{
var result = await GetPagedResult(client, url, page);
return result;
}
finally
{
throttler.Release();
}
}));
}
await Task.WhenAll(allTasks);
foreach (var task in allTasks)
{
var result = ((Task<PagedResultResponse>)task).Result;
rtn.Add(result);
}
return rtn; …Run Code Online (Sandbox Code Playgroud) semaphore ×10
c++ ×4
c ×2
interprocess ×2
java ×2
linux ×2
pthreads ×2
asp.net-core ×1
boost ×1
c# ×1
concurrency ×1
file ×1
memory ×1
perl ×1
shared ×1