操作信号量级来进行交替报数

#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);  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值