关于 信号量操作函数semop 报 Invalid argument错误的问题

only_yestoday 2013-08-02 08:23:18
主函数是把信号量 V了两次,然后又P几次,这是没问题的,当信号量得值变成0之后再V操作的话,信号量的值变成-1后程序就阻塞了。可是当我在当我开了几个线程后,然后在线程里面去进行P操作问题就出来了,如标题写的那样,semop函数会报Invalid argument错误,而且线程不会阻塞。大侠们帮帮忙吧,刚接触LINUX
另外还是工作需要。测试程序如下面,并一起给出MAKEFILE

#include <malloc.h>
#include<sys/types.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<ctype.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<signal.h>
#include<sys/wait.h>
#include<sys/select.h>
#include<fcntl.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<pthread.h>

union semun
{
int val; // value for SETVAL
struct semid_ds *buf; // buffer for IPC_STAT, IPC_SET
unsigned short *array; // array for GETALL, SETALL
// Linux specific part
struct seminfo *__buf; // buffer for IPC_INFO
};

int sid;

int CreateSem(const char *pathname, int subid, int members, int initvar)
{
key_t key;
int sid,index;
union semun semopts;
if((key=ftok(pathname, subid))==-1)
{
perror("ftok erro!");
return -1;
}

if((sid=semget(key, members, IPC_CREAT))==-1)
{
perror("Fail to create semaphore !");
return -1;
}
semopts.val = initvar;
for(index = 0; index < members; index++)
{
semctl(key, index, SETVAL, semopts);
}
return sid;
}

int Delete_Sem(int semid)
{
union semun semopts;
if(semctl(semid, 0, IPC_RMID, semopts) == -1)
{
perror("Failed to delete semaphore!");
return -1;
}
return 0;

}

int Set_SemValue(int semid, int index, int value)
{
union semun semopts;
semopts.val=value;
if(semctl(semid, index, SETVAL, semopts) == -1)
{
perror("Failed to set semaphore!");
return -1;
}
return 0;
}

int Sem_P(int semid, int index)
{
struct sembuf buf={0, -1, SEM_UNDO};
if(index < 0)
{
perror("index of arry can not be minus value!");
return -1;
}
buf.sem_num = index;
if(semop(semid, &buf, 1) == -1)
{
perror("semop erro!");
return -1;
}
return 0;
}

int Sem_V(int semid, int index)
{
struct sembuf buf={0, 1, SEM_UNDO};
if(index < 0)
{
perror("index of arry can not be minus value!");
return -1;
}
buf.sem_num = index;
if(semop(semid, &buf, 1) == -1)
{
perror("semop erro!");
return -1;
}
return 0;
}

void thread1(void *arg)
{
while(1)
{
printf("thread1 runing\n");
sleep(1);
Sem_P(sid, 0);
int ret=semctl(sid, 0, GETVAL, 0 );
printf ("thread1 : %d %d\n", sid,ret);
}
}

void thread2(void *arg)
{
while(1){
printf ("thread2 running\n");
sleep(1);
Sem_P(sid, 0);
int ret=semctl(sid, 0, GETVAL, 0 );
printf ("thread 2 : %d %d\n", sid,ret);
}
}

void thread3(void *arg)
{
while(1)
{
printf ("thread3 running\n");
sleep(1);
// int ret=semctl(sid, 0, GETVAL, 0 );
// printf ("thread3 : %d %d\n", sid,ret);
}
}

int main(int argc, char *argv[], char *envp[])
{
pthread_t tid;
sid=CreateSem(".", 1, 2, 0);
Sem_V(sid, 0);
int ret=semctl(sid, 0, GETVAL, 0 );
printf ("%d %d\n", sid,ret);
Sem_V(sid, 0);
ret=semctl(sid, 0, GETVAL, 0 );
printf ("%d %d\n", sid,ret);
Sem_P(sid, 0);
ret=semctl(sid, 0, GETVAL, 0 );
printf ("%d %d\n", sid,ret);
Sem_P(sid, 0);
ret=semctl(sid, 0, GETVAL, 0 );
printf ("%d %d\n", sid,ret);

pthread_create(&tid, NULL, (void*)thread1, NULL);
pthread_create(&tid, NULL, (void*)thread2, NULL);
pthread_create(&tid, NULL, (void*)thread3, NULL);


Delete_Sem(sid);

sleep(30);

return 1;
}







//提供个make file可直接调试看效果

APPNAME:=test.out
SRC:=$(wildcard *.c)
OBJS:=$(patsubst %.c,%.o,$(SRC))
OPTFLAG:= -g -mtune=generic
LIBS:= -lpthread

all:$(APPNAME)

$(APPNAME):$(OBJS)
gcc $(OPTFLAG) $^ $(LIBS) -o $@

clean:
rm -rf *.o *.out *.d

%.d: %.c
@set -e; rm -f $@; \
$(CC) -MM $(CPPFLAGS) $< > $@; \


#-include $(SRC:.c=.d)

.PHONY:all
.PHONY:clean

$(filter %.o,$(OBJS)):%.o:%.c
gcc -c $(OPTFLAG) $< -o $@






...全文
1393 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
only_yestoday 2013-08-02
  • 打赏
  • 举报
回复
引用 1 楼 Idle_Cloud 的回复:
线程的pthread_t tid;不要定义成一个定义成tid1,tid2,tid3 在Delete_Sem(sid);之前加如下三句 pthread_join( tid, NULL ); pthread_join( tid2, NULL ); pthread_join( tid3, NULL ); 不然很快执行这句Delete_Sem(sid); 就不行了。
啥也别说了,谢谢你
only_yestoday 2013-08-02
  • 打赏
  • 举报
回复
Carl_CCC 2013-08-02
  • 打赏
  • 举报
回复
线程的pthread_t tid;不要定义成一个定义成tid1,tid2,tid3
在Delete_Sem(sid);之前加如下三句

pthread_join( tid, NULL );
pthread_join( tid2, NULL );
pthread_join( tid3, NULL );

不然很快执行这句Delete_Sem(sid); 就不行了。

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧