信号量初始资源为1,3个进程同时执行到semop函数,然后一个进程获得了资源.另外两个进程等待,但在第1个进程释放资源后,另外2个进程都获取到了资源,然后2个进程就都往下执行了..
我希望的是semop下面的代码,同时只有1个进程在执行,另外2个进程等待
key_t key;
key = ftok("/", 0);
int semid = semget(key, 1, IPC_CREAT| IPC_EXCL |0666);
if (semid == -1)
{
semid = semget(key, 1, IPC_EXCL |0666);//信号量已存在
}
else
semctl(semid, 0, SETVAL, 1); /*设置索引0的信号量*/
int getvalue = semctl(semid, 0, GETVAL, 0);
struct sembuf acquire = {0, -1, SEM_UNDO};
struct sembuf release = {0, 1, SEM_UNDO};
if (-1 == semop(semid,&acquire,1))//第1个进程释放资源后,另外2个进程都不再阻塞这这里了,需要解决
{
return 0;
}
...... //代码块,同一时刻只能1个进程执行
semop(semid,&release,1);
13 个解决方案
#1
跟踪一下semid的值是多少
另外,最好不要这么定义struct sembuf acquire = {0, -1, SEM_UNDO};
也许你的系统中sembuf各个成员的顺序和你预期的不一致
另外,最好不要这么定义struct sembuf acquire = {0, -1, SEM_UNDO};
也许你的系统中sembuf各个成员的顺序和你预期的不一致
#2
semid 都是一样的.
我的问题是这样的,程序执行步骤
1:3个进程都创建或打开同一个信号量
2:初始化信号量资源为1
3:进程1获得了资源,进程2和进程3等待
4:进程1是否资源,进程1退出
5:在进程1是否资源后,进程2和进程3同时不再阻塞了,往下执行..
问题就在第5部,应该让进程2和进程3,在进程1释放信号量时,只能是进程2获取资源然后执行,进程3依然等待直到进程2释放资源
#3
确认一下,是不是3个进程都执行了semctl(semid, 0, SETVAL, 1);
这样,即使一个进程获取了信号灯,值为0了,另外一个进程还是把它的值重新设置为1了
这样,即使一个进程获取了信号灯,值为0了,另外一个进程还是把它的值重新设置为1了
#4
只有1个进程执行了semctl(semid, 0, SETVAL, 1);
因为我在semop之前打印出来了资源数
int getvalue = semctl(semid, 0, GETVAL, 0);
printf("sem value is %d ", getvalue);
打印出来第1个进程为1,其他2个进程都为0
因为我在semop之前打印出来了资源数
int getvalue = semctl(semid, 0, GETVAL, 0);
printf("sem value is %d ", getvalue);
打印出来第1个进程为1,其他2个进程都为0
#5
进程1操作完成之后,进程退出了吗?
#6
实际上是进程1的1个线程执行这块代码的。执行完后这个线程就退出了。但是进程1,2,3都是一直运行的
3个进程是同一份代码
#7
会不会与SEM_UNDO标志有关?
#8
我今天再试试!我对信号量不熟!
#9
跟SEM_UNDO标识没关系
#10
你说3个进程是同一份代码,那应该都执行这个semctl 了啊..
你每次执行都是一样的结果吗?
要不你把完整代码贴上来看看?
#11
完整代码实际上前面的那部分就是了,这只是整个程序中的一个线程函数而已.
semctl 只会执行一次啊,因为第1个进程创建了信号量,第2,3个线程就会创建失败,然后它们就做打开信号量的操作..
我放弃了,不搞了,我现在打算重新编译我的mysql数据库,因为我做这个信号量的步骤就是为了解决3个进程同时connect mysql的时候进程会死掉的问题。
只能把Mysql客户端编译成安全的。。
#12
第2、3个进程使用semget打开信号量,但是他们也执行semctl 了
#13
但是我打印出来,第2,3个进程的信号量的值都为0..
#1
跟踪一下semid的值是多少
另外,最好不要这么定义struct sembuf acquire = {0, -1, SEM_UNDO};
也许你的系统中sembuf各个成员的顺序和你预期的不一致
另外,最好不要这么定义struct sembuf acquire = {0, -1, SEM_UNDO};
也许你的系统中sembuf各个成员的顺序和你预期的不一致
#2
semid 都是一样的.
我的问题是这样的,程序执行步骤
1:3个进程都创建或打开同一个信号量
2:初始化信号量资源为1
3:进程1获得了资源,进程2和进程3等待
4:进程1是否资源,进程1退出
5:在进程1是否资源后,进程2和进程3同时不再阻塞了,往下执行..
问题就在第5部,应该让进程2和进程3,在进程1释放信号量时,只能是进程2获取资源然后执行,进程3依然等待直到进程2释放资源
#3
确认一下,是不是3个进程都执行了semctl(semid, 0, SETVAL, 1);
这样,即使一个进程获取了信号灯,值为0了,另外一个进程还是把它的值重新设置为1了
这样,即使一个进程获取了信号灯,值为0了,另外一个进程还是把它的值重新设置为1了
#4
只有1个进程执行了semctl(semid, 0, SETVAL, 1);
因为我在semop之前打印出来了资源数
int getvalue = semctl(semid, 0, GETVAL, 0);
printf("sem value is %d ", getvalue);
打印出来第1个进程为1,其他2个进程都为0
因为我在semop之前打印出来了资源数
int getvalue = semctl(semid, 0, GETVAL, 0);
printf("sem value is %d ", getvalue);
打印出来第1个进程为1,其他2个进程都为0
#5
进程1操作完成之后,进程退出了吗?
#6
实际上是进程1的1个线程执行这块代码的。执行完后这个线程就退出了。但是进程1,2,3都是一直运行的
3个进程是同一份代码
#7
会不会与SEM_UNDO标志有关?
#8
我今天再试试!我对信号量不熟!
#9
跟SEM_UNDO标识没关系
#10
你说3个进程是同一份代码,那应该都执行这个semctl 了啊..
你每次执行都是一样的结果吗?
要不你把完整代码贴上来看看?
#11
完整代码实际上前面的那部分就是了,这只是整个程序中的一个线程函数而已.
semctl 只会执行一次啊,因为第1个进程创建了信号量,第2,3个线程就会创建失败,然后它们就做打开信号量的操作..
我放弃了,不搞了,我现在打算重新编译我的mysql数据库,因为我做这个信号量的步骤就是为了解决3个进程同时connect mysql的时候进程会死掉的问题。
只能把Mysql客户端编译成安全的。。
#12
第2、3个进程使用semget打开信号量,但是他们也执行semctl 了
#13
但是我打印出来,第2,3个进程的信号量的值都为0..