我正在研究一个我们必须使用信号量来解决的问题.我有一个数组,其中包含两个信号量,gsem并给出一定的条件调用sem_wait(&(gsem[me])),这应该等到特定进程被唤醒.但是,出于某种原因,它给了我错误Bad file descriptor.我向上看sem_wait,Open Group规范说这不是错误sem_wait导致的.这让我的整个程序变得疯狂,我不知道为什么会失败.
编辑:违规代码,根据要求.
120 sem_wait(&mutex);
121 if (inside[opp] > 0 || waiting[opp] > 0) {
122 sem_wait(&screen);
123 printf("%s %u waiting\n", names[me], t);
124 sem_post(&screen);
125 waiting[me]++;
126 sem_post(&mutex);
127 int hg = sem_wait(&(gsem[me]));
128 if (hg < 0)
129 printf("%s\n", strerror(errno));
130 }
Run Code Online (Sandbox Code Playgroud)
我应该注意这是一项家庭作业,我们需要使用信号量.教授称之为"男女皆宜的浴室".男人和女人都可以使用它,但不能同时使用它.inside[opp]是浴室里异性的人数.waiting[opp]是等待使用它的异性的数量.screen是一个锁定访问权限的信号量stdout.该解决方案基于我们的教科书中使用传递接力棒的读者/作者问题的解决方案.
我还应该注意,我们首先必须在Ada中编写解决方案,然后将其转换为C.我的Ada解决方案有效,我逐字翻译.我确定这是一些小的语法细节.最后,我正在研究Snow Leopard,如果有帮助的话.
我为生产者和消费者实现了一个信号量类.
它工作正常,但我现在感觉我们使用notifyAll来通知唤醒或通知所有线程的线程.
我想知道是否有任何方式我们只能通知一组特定的组:生成器只使用组或其他任何方式通知消费者线程,反之亦然.
PS:我是java和Threading的新手.
操作系统:Windows.语言:C
我有一个线程通过TCP向服务器发送请求,并在信号量上无限期等待响应.还有另一个线程读取套接字,将接收到的数据复制到公共缓冲区中,并使信号脉冲,以便从等待中退出.这一切都很好.但是在由于某种原因导致进程被终止的情况下,等待信号量的线程在其他线程终止时等待.
为什么线程等待信号量在进程被杀死时不会结束?我在Linux论坛上看到SEM_UNDO在这种情况下有所帮助.Windows上有类似的东西吗?任何解决方法?
我在一个过程中有两个线程.这两个线程竞争共享内存,尝试通过信号量进行同步.但是当一个线程紧挨着另一个线程调用semop函数时,我随机地使用errno 4失败了.我做了一点挖掘,发现似乎呼叫被系统调用打断了.
EINTR在此系统调用中被阻止时,该过程发出信号; 见信号(7).errno 4是这个吗?
请注意第583和601行.
哪个系统调用打断了它?函数semop()本身?有什么方法可以忽略这个系统调用中断或恢复/重启这个功能?
semop可以在多线程环境中使用吗?
[Switching to Thread -1208269120 (LWP 4501)]
GetMyQue2Wait (MyModule=RM, wait_shm_ptr=0xbf8a5cf4) at tdm_ipc.c:247
247 TDM_SEM_P( MyModule );
(gdb) s
tdm_sem_p (mid=RM) at tdm_ipc.c:579
579 sem_b.sem_num = 0;
(gdb) s
580 sem_b.sem_op = -1;
(gdb) s
581 sem_b.sem_flg = SEM_UNDO;
(gdb) s
583 if (semop(TDM_M[mid].semid, &sem_b, 1) == -1)
(gdb) s
[Switching to Thread -1208480880 (LWP 4506)]
GetMyQue2Send (MyModule=RM, send_shm_ptr=0xb7f7ff54) at tdm_ipc.c:180
180 DMINT TryTimes = SEND_TIMES;
(gdb) s
353 TDM_SEM_V( DstModule );
(gdb) s …Run Code Online (Sandbox Code Playgroud) 我对线程和进程级别的信号量和互斥量的使用感到困惑.我们可以使用semphores和互斥量进行线程和进程同步,还是在线程和进程级别都有不同的信号量和互斥量?我的问题是参考POSIX API.
假设有许多线程调用该方法m(int i)并将数组的值更改为位置i.以下代码是否正确,或者是否存在竞争条件?
public class A{
private int []a =new int[N];
private Semaphore[] s=new Semaphore[N];
public A(){
for(int i =0 ; i<N ; i++)
s[i]=new Semaphore(1);
}
public void m(int i){
s[i].acquire();
a[i]++;
s[i].release();
}
}
Run Code Online (Sandbox Code Playgroud) 当前信号量的实现如何工作?它使用自旋锁或信号吗?
如果使用信号,调度程序如何知道调用哪一个?
它在用户空间中如何工作?内核锁定建议使用自旋锁,但用户空间不会.那么信号量的用户空间和内核空间的实现是否也不同?
我想实现一个锁机制,所以只有一个线程可以运行一个代码块.但我不希望其他线程等待锁定对象,如果它被锁定,它们应该什么都不做.所以它与标准锁机制略有不同.
if (block is not locked)
{
// Do something
}
else
{
// Do nothing
}
Run Code Online (Sandbox Code Playgroud)
在C#中执行此操作的最佳方法是什么?
我正在尝试使用sem_timedwait()来重复锁定和解锁信号量.根据这里的示例,我按以下方式设置我的struct timespec,延迟20毫秒:
sem_t semaphore; //initialized somewhere else
void waitForSomething ()
{
int ret;
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
{
//throw error
}
ts.tv_nsec += 20000000; //timeout of 20 msec
while ((ret = sem_timedwait(&semaphore, &ts)) == -1 && errno == EINTR)
continue;
if (ret == -1 && errno != ETIMEDOUT) {
//flag error
} else {
//do something
}
return;
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,我的程序在使用EINVAL错误代码运行一段时间后会一直失败.经过调试后,我意识到失败的原因是ts.tv_nsec在一段时间后超过了1000000000.我目前的解决方法如下:
sem_t semaphore; //initialized somewhere else
void waitForSomething ()
{
int ret;
struct timespec ts; …Run Code Online (Sandbox Code Playgroud) 我有一个通用的Windows构建批处理(即build.bat),它与不同的参数并行运行.
start build.bat device1
start build.bat device2
start build.bat device3
Run Code Online (Sandbox Code Playgroud)
但在该批处理中,有一个可执行文件在并行调用时崩溃.
使用Windows内置函数时,是否可以在已经在另一个批处理中运行时阻止此调用,并在完成另一个批处理时继续执行此操作?
假设该批次的内容是
start delay 5
Run Code Online (Sandbox Code Playgroud)
当多次调用批处理时,当另一个延迟当前正在运行时,延迟不得运行.
这与信号量类似.
所以我的目标是拥有这样的东西
CheckAndWaitIfDelayIsRunning
start delay 5
Run Code Online (Sandbox Code Playgroud)
提前致谢.