#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <string.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <pthread.h>
void* task1(void *arg);
void* task2(void *arg);
void* task3(void *arg);
int i = 0;
typedef union semnum
{
/* data */
int val;
unsigned short *arry;
}SEM;
SEM sembuf;
int main(int argc, char *argv[])
{
int ret;
pthread_t tid1,tid2,tid3;
int smid;
key_t key;
key = ftok(argv[1],2);
if(key == -1)
{
perror("ftok error\r\n");
return 0;
}
printf("key = %d\r\n",key);
smid = semget(key,3,IPC_CREAT | 0666);
if(smid == -1)
{
perror("semget error\r\n");
return 0;
}
memset(&sembuf,0,sizeof(sembuf));
sembuf.val = 0;
****/此处设置初始值,级别你设置了值,但是你还是要在进行信号量的访问的,因此值的设置还不如放到线程当中以便更好的修改后面出现的bug
semctl(smid,0,SETVAL,sembuf);
semctl(smid,1,SETVAL,sembuf);
semctl(smid,2,SETVAL,sembuf);
/**********************************************************************
printf("smid = %d\r\n",smid);
rec1 = semctl(smid,0,GETVAL);
printf("rec1 = %d\r\n",rec1);
rec2 = semctl(smid,1,GETVAL);
printf("rec2 = %d\r\n",rec2);
rec3 = semctl(smid,2,GETVAL);
printf("rec3 = %d\r\n",rec3);
pthread_create(&tid1,NULL,task1,(void*)1);
pthread_create(&tid2,NULL,task2,(void*)2);
pthread_create(&tid3,NULL,task3,(void*)3);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_join(tid3,NULL);
ret=semctl(smid,0,IPC_RMID);
printf("ret = %d\r\n",ret);
exit(0);
return 0;
}
void* task1(void* arg)
{
long a;
a = (long)arg;
/*************验证信号量集里面的信号值进行+或-操作时候是否能够达到阻塞的功能,答案是正确的,其他的进行2、3分别对信号集中的信号2、信号3进行-1,因为初始值为0,因此对其进行减操作时候,值小于,因此会被阻塞掉,因此sleep结束后还是会回到线程 的
**************************************************************************/
sleep(1);
/*****************休眠结束后,下面开始进行加操作+,以便后面阻塞线程,********************************/
struct sembuf sop1[1] = {{0,+1,0}};
semop(smid,sop1,1);
while(1)
{
if(i>=100)
{
*****/这里需要释放下面的线程,以免被阻塞掉,回不到主进程***************************/
*******/释放掉线程2*********/
struct sembuf sop5[1] = {{1,2,0}};
semop(smid,sop5,1);
pthread_exit(NULL);
break;
}
********/将上次设置对信号1进行加1操作后,信号量的值为1,因此我们需要-1,以便后面的阻塞*********/
struct sembuf sop4[1] = {{0,-1,0}};
semop(smid,sop4,1);
i++;
printf("child%ld: %d\r\n",a,i);
if(i>=100)
{
struct sembuf sop6[1] = {{1,2,0}};
semop(smid,sop6,1);
pthread_exit(NULL);
break;
}
*******/释放掉线程2*********/
struct sembuf sop2[1] = {{1,2,0}};
semop(smid,sop2,1);
*******/阻塞掉线程1*********/
struct sembuf sop3[1] = {{0,-1,0}};
semop(smid,sop3,1);
if(i>=100)
{
break;
}
}
pthread_exit(NULL);
}
void* task2(void* arg)
{
long a;
a = (long)arg;
while(1)
{
struct sembuf sop1[1] = {{1,-1,0}};
semop(smid,sop1,1);
i++;
if(i>=100)
{
struct sembuf sop5[1] = {{2,1,0}};
semop(smid,sop5,1);
break;
}
printf("child%ld: %d\r\n",a,i);
struct sembuf sop2[1] = {{2,2,0}};
semop(smid,sop2,1);
struct sembuf sop3[1] = {{1,-1,0}};
semop(smid,sop3,1);
if(i>=100)
{
struct sembuf sop5[1] = {{2,1,0}};
semop(smid,sop5,1);
break;
}
}
pthread_exit(NULL);
}
void* task3(void* arg)
{
long a;
a = (long)arg;
while(1)
{
struct sembuf sop1[1] = {{2,-1,0}};
semop(smid,sop1,1);
if(i>=100)
{
break;
}
i++;
printf("child%ld: %d\r\n",a,i);
struct sembuf sop2[1] = {{0,2,0}};
semop(smid,sop2,1);
struct sembuf sop3[1] = {{2,-1,0}};
semop(smid,sop3,1);
if(i>=100)
{
break;
}
}
pthread_exit(NULL);
}