linux多线程编程多个信号量怎么使用

linux多线程编程多个信号量怎么使用,第1张

生产者消费者访问的都是同一个共享对象,这个共享对象提供读写 *** 作,然后生产者线程调用写 *** 作,消费者线程调用同一对象读 *** 作,在这个共享对象里定义一个信号量,在读写成员函数中保证互斥就行了。估计你用的是Win32 API 或者 Pthread API吧。。。。呵呵,那些东西太底层了。

不是信号量的问题

printf函数,是先写到输出缓冲,遇到\n时,或者缓冲区满时,或者有强制输出(fflush)时,才会将缓冲区里的内容输出到屏幕上(标准输出设备:stdout)。你的代码里面并没有以上3个触发条件的任意一种,所以printf的内存没有实际输出到屏幕上。

你只要在每个printf函数后面加上fflush(stdout);就可以了。

sem_t是linux下的信号量

头文件:

#include <semaphoreh>

初始化

int sem_init (sem_t sem, int pshared, unsigned int value);

激活:

int sem_post(sem_t sem);

等待:

int sem_wait(sem_t sem);

int sem_trywait(sem_t sem);

int sem_timedwait(sem_t sem, const struct timespec abs_timeout);

释放:

int sem_destroy (sem_t sem);

信号量与互斥锁之间的区别:1 互斥量用于线程的互斥,信号量用于线程的同步。 这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源 2 互斥量值只能为0/1,信号量值可以为非负整数。 也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。 3 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。

分配与初始化信号量是两个相互独立的 *** 作。以 0 为第二参数,以 SETALL 为第三个参数调用 semctl 可以对一个信号量组进行初始化。第四个参数是一个 semun 对象,且它的 array 字段指向一个 unsigned short数组。数组中的每个值均用于初始化该组中的一个信号量。

代码 53 展示了初始化一个二元信号量的函数。

代码 53 (sem_initc) 初始化一个二元信号量

#include <sys/typesh>

#include <sys/ipch>

#include <sys/semh>

/ 我们必须自己定义 union semun。/

union semun

{

int val;

struct semid_ds buf;

unsigned short int array;

struct seminfo __buf;

};

/ 将一个二元信号量初始化为 1。/

int binary_semaphore_initialize (int semid)

{

union semun argument;

unsigned short values[1];

values[0] = 1;

argumentarray = values;

return semctl (semid, 0, SETALL, argument);

}

生产者/消费者问题在windows2000下的实现

一、问题描述

生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。本作业要求设计在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

二、实现代码

#include <windowsh>

#include <iostream>

const unsigned short SIZE_OF_BUFFER = 10; //缓冲区长度

unsigned short ProductID = 0; //产品号

unsigned short ConsumeID = 0; //将被消耗的产品号

unsigned short in = 0; //产品进缓冲区时的缓冲区下标

unsigned short out = 0; //产品出缓冲区时的缓冲区下标

int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列

bool g_continue = true; //控制程序结束

HANDLE g_hMutex; //用于线程间的互斥

HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待

HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待

DWORD WINAPI Producer(LPVOID); //生产者线程

DWORD WINAPI Consumer(LPVOID); //消费者线程

int main()

{

//创建各个互斥信号

g_hMutex = CreateMutex(NULL,FALSE,NULL);

g_hEmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);

//调整下面的数值,可以发现,当生产者个数多于消费者个数时,

//生产速度快,生产者经常等待消费者;反之,消费者经常等待

const unsigned short PRODUCERS_COUNT = 3; //生产者的个数

const unsigned short CONSUMERS_COUNT = 1; //消费者的个数

//总的线程数

const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;

DWORD producerID[CONSUMERS_COUNT]; //生产者线程的标识符

DWORD consumerID[THREADS_COUNT]; //消费者线程的标识符

//创建生产者线程

for (int i=0;i<PRODUCERS_COUNT;++i){

hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);

if (hThreads[i]==NULL) return -1;

}

//创建消费者线程

for (int i=0;i<CONSUMERS_COUNT;++i){

hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]);

if (hThreads[i]==NULL) return -1;

}

while(g_continue){

if(getchar()){ //按回车后终止程序运行

g_continue = false;

}

}

return 0;

}

//生产一个产品。简单模拟了一下,仅输出新产品的ID号

void Produce()

{

std::cerr << "Producing " << ++ProductID << " ";

std::cerr << "Succeed" << std::endl;

}

//把新生产的产品放入缓冲区

void Append()

{

std::cerr << "Appending a product ";

g_buffer[in] = ProductID;

in = (in+1)%SIZE_OF_BUFFER;

std::cerr << "Succeed" << std::endl;

//输出缓冲区当前的状态

for (int i=0;i<SIZE_OF_BUFFER;++i){

std::cout << i <<": " << g_buffer[i];

if (i==in) std::cout << " <-- 生产";

if (i==out) std::cout << " <-- 消费";

std::cout << std::endl;

}

}

//从缓冲区中取出一个产品

void Take()

{

std::cerr << "Taking a product ";

ConsumeID = g_buffer[out];

out = (out+1)%SIZE_OF_BUFFER;

std::cerr << "Succeed" << std::endl;

//输出缓冲区当前的状态

for (int i=0;i<SIZE_OF_BUFFER;++i){

std::cout << i <<": " << g_buffer[i];

if (i==in) std::cout << " <-- 生产";

if (i==out) std::cout << " <-- 消费";

std::cout << std::endl;

}

}

//消耗一个产品

void Consume()

{

std::cerr << "Consuming " << ConsumeID << " ";

std::cerr << "Succeed" << std::endl;

}

//生产者

DWORD WINAPI Producer(LPVOID lpPara)

{

while(g_continue){

WaitForSingleObject(g_hFullSemaphore,INFINITE);

WaitForSingleObject(g_hMutex,INFINITE);

Produce();

Append();

Sleep(1500);

ReleaseMutex(g_hMutex);

ReleaseSemaphore(g_hEmptySemaphore,1,NULL);

}

return 0;

}

//消费者

DWORD WINAPI Consumer(LPVOID lpPara)

{

while(g_continue){

WaitForSingleObject(g_hEmptySemaphore,INFINITE);

WaitForSingleObject(g_hMutex,INFINITE);

Take();

Consume();

Sleep(1500);

ReleaseMutex(g_hMutex);

ReleaseSemaphore(g_hFullSemaphore,1,NULL);

}

return 0;

}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/12163893.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存