导航网站链接怎么做,建设网站的费用调研,网站地图的使用,网站建设属于哪种公司菜鸟偶遇信号量#xff0c;擦出火花#xff08;只有不熟才会有火花#xff09;。于是上网搜资料和看《Unix环境高级编程》实现了几个小例题#xff0c;高手请勿喷#xff01;这几位写得非常好啊#xff1a; 题目来源#xff1a; http://www.it165.net/os/html/201312/70… 菜鸟偶遇信号量擦出火花只有不熟才会有火花。于是上网搜资料和看《Unix环境高级编程》实现了几个小例题高手请勿喷这几位写得非常好啊 题目来源 http://www.it165.net/os/html/201312/7039.html 信号量及其用法http://www.cnblogs.com/hjslovewcl/archive/2011/03/03/2314341.html Mutex与Semaphore区别著名的厕所理论http://koti.mbnet.fi/niclasw/MutexSemaphore.html 哎呀暴露了我不是故意偷窥别人的…… 一一个生产者、一个消费者、一个资源情况 这种情况情况可以只用一个信号量要生成或要消费只用尝试获取这个信号量这里用了两个full1和empty0两个只为了和后面一致1、0是赋初值。生产者和消费者情况如下 //生产者
P(empty)生成资源并放进资源处
V(full)//消费者
P(full)消费资源
V(empty) 若生产者最先开始生产资源P(empty)full和empty都成了0此时若消费者想要消费则P(full)时full为0则睡眠等待等生产者生结束就把full加1看到消费者可怜地睡着了就唤醒它然后消费者把full减1自己快活去了。 消费者消费过程中生产者若要生了则会因为empty为0而休眠等消费者结束就把empty加1然后生产者开始生产。 上面的好理解下面上代码: #include stdio.h
#include stdlib.h
#include unistd.h
#include pthread.h#include x86_64-linux-gnu/sys/types.h
#include x86_64-linux-gnu/sys/ipc.h
#include x86_64-linux-gnu/sys/sem.hint semInite(int semId, int value);
int semDelete(int semId);
int semP(int semId);
int semV(int semId);//declare a union to be used
union semun
{int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short int *array; /* array for GETALL, SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */
};//semaphore declare
static int semFullId;
static int semEmptyId;
static int source 0; //source definition //new thread as a consumer
void* child_thread(void* arg)
{int ttt 1;while(1){sleep(rand() % 19);printf(child No.%d times wants to consume...\n, ttt);semP(semFullId); //printf(child No.%d times start consuming. source %d\n, ttt, source);source 0;printf(child No.%d times end consuming. source %d\n\n, ttt, source);semV(semEmptyId); //}return (void*)0;
}int main(void)
{ //create semaphoresemFullId semget((key_t)1235, 1, 0666 | IPC_CREAT);semEmptyId semget((key_t)1236, 1, 0666 | IPC_CREAT);semInite(semFullId, 0);semInite(semEmptyId, 1);pthread_t pid;pthread_create(pid, NULL, child_thread, NULL);int tt 1; while(1){sleep(rand() % 18);printf(parent No.%d times wants to produce...\n, tt);semP(semEmptyId); //printf(parent No.%d times start producing. source %d\n, tt, source);source rand() % 100;printf(parent No.%d times end producing. source %d\n, tt, source);semV(semFullId); //}semDelete(semFullId);semDelete(semEmptyId);return 0;
}//set semaphore as default value
int semInite(int semId, int value)
{union semun semUnion;semUnion.val value; //set default semaphorereturn semctl(semId, 0, SETVAL, semUnion);
}//delete semaphore
int semDelete(int semId)
{union semun semUnion;return semctl(semId, 0, IPC_RMID, semUnion);
}//semaphore P operation
int semP(int semId)
{struct sembuf semBuf;semBuf.sem_num 0; //indicate it is not semaphore arraysemBuf.sem_op -1; //subtract onesemBuf.sem_flg SEM_UNDO;return semop(semId, semBuf, 1); //return value
}//semaphore V operation
int semV(int semId)
{struct sembuf semBuf;semBuf.sem_num 0; //indicate it is not semaphore arraysemBuf.sem_op 1; //subtract onesemBuf.sem_flg SEM_UNDO;return semop(semId, semBuf, 1); //return value
} 111 两个信号量其实应该用信号量集的因为它本来就是针对集合的但是由于刚入门为了易懂就用两个。两个线程创建的新线程当做消费者了。其中unix的几个信号量的函数看了半天有点复杂简单不准确来讲 //获得一个信号量啦第二个参数是想要创建的信号量个数
//因为unix操作的是信号量集合设为1不就一个信号量了嘛
//其他参数我不管了
int semget(key_t key, int num_sems, int sem_flags);//信号量集合的操作这个可以用来实现P、V的 1 -1 的功能
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);//信号量集合的控制如初始化删除等
int semctl(int sem_id, int sem_num, int command, ...); 运行 二一个生产者、一个消费者、N个资源情况 这里资源用是一个数组代替了。其实本质上和上面类似每次只让生产者或消费者中的一个进入进入后放到哪个地方或从哪个地方取就得用一个标志来说明了其实也可以为每一资源加上信号量的。 这里在生产者和消费者那里都设置了一个static的变量当做游标指示下个资源放到哪个位置和下次从哪取资源。staitic变量用在这里很合适因为只会初始化一次。 #include stdio.h
#include stdlib.h
#include unistd.h
#include pthread.h#include x86_64-linux-gnu/sys/types.h
#include x86_64-linux-gnu/sys/ipc.h
#include x86_64-linux-gnu/sys/sem.h#define N 5int semInite(int semId, int value);
int semDelete(int semId);
int semP(int semId);
int semV(int semId);//declare a union to be used
union semun
{int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short int *array; /* array for GETALL, SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */
};//semaphore declare
static int semFullId;
static int semEmptyId;
static int srcArr[N]; //source definition //new thread as a consumer
void* child_thread(void* arg)
{int ttt 1;while(1){static int pToGet 0; //get source from the positionsleep(rand() % 19);printf(child No.%d times wants to consume(get from index %d)...\n, ttt, pToGet);semP(semFullId); //printf(child No.%d times start consuming.(get from index %d, data is %d)\n, ttt, pToGet, srcArr[pToGet]);srcArr[pToGet] 0;printf(child No.%d times end consuming. (get from index %d)\n\n, ttt, pToGet);pToGet (pToGet 1) % N;semV(semEmptyId); //}return (void*)0;
}int main(void)
{ //create semaphoresemFullId semget((key_t)1235, 1, 0666 | IPC_CREAT);semEmptyId semget((key_t)1236, 1, 0666 | IPC_CREAT);semInite(semFullId, 0);semInite(semEmptyId, N); //N sourcepthread_t pid;pthread_create(pid, NULL, child_thread, NULL);int tt 1; while(1){static int pToPut 0; //next position where source to be filled insleep(rand() % 18);printf(parent No.%d times wants to produce(put in %d index)...\n, tt, pToPut);semP(semEmptyId); //printf(parent No.%d times start producing.(put in %d index, original data is %d)\n, tt, pToPut, srcArr[pToPut]);int temp rand() % 100;srcArr[pToPut] temp;printf(parent No.%d times end producing.(put in %d index, now data is %d)\n, tt, pToPut, srcArr[pToPut]);pToPut (pToPut 1) % N;semV(semFullId); //}semDelete(semFullId);semDelete(semEmptyId);return 0;
}//set semaphore as default value
int semInite(int semId, int value)
{union semun semUnion;semUnion.val value; //set default semaphorereturn semctl(semId, 0, SETVAL, semUnion);
}//delete semaphore
int semDelete(int semId)
{union semun semUnion;return semctl(semId, 0, IPC_RMID, semUnion);
}//semaphore P operation
int semP(int semId)
{struct sembuf semBuf;semBuf.sem_num 0; //indicate it is not semaphore arraysemBuf.sem_op -1; //subtract onesemBuf.sem_flg SEM_UNDO;return semop(semId, semBuf, 1); //return value
}//semaphore V operation
int semV(int semId)
{struct sembuf semBuf;semBuf.sem_num 0; //indicate it is not semaphore arraysemBuf.sem_op 1; //subtract onesemBuf.sem_flg SEM_UNDO;return semop(semId, semBuf, 1); //return value
} 222 运行结果 三N个生产者N个消费者N个资源 这种情况不仅生产者和消费者之间要通过上述的方式协调使用资源而且生产者内部和消费者内部也要协调。定义四个信号量 empty——表示缓冲区是否为空初值为n。full——表示缓冲区中是否为满初值为0。mutex1——生产者之间的互斥信号量初值为1。mutex2——消费者之间的互斥信号量初值为1。 //生产者进程
P(mutex1)P(empty)生产数据并放进特定位置V(full)
V(mutex1)//消费者进程
P(mutex2)P(full)消费数据V(empty)
V(mutex2) 其实上面生产者或者消费者获取互斥量或信号量的顺序可以颠倒的不会产生死锁。 当然这个问题可以用其他更好的方式解决我还得继续学习。 转载于:https://www.cnblogs.com/jiayith/p/3854312.html