导航:首页 > 网络营销 > c语言sem

c语言sem

发布时间:2020-12-18 15:34:29

1、用C语言实现--生产者与消费者的问题(PV操作)

这个问题蛮好的
我给你个程序
给我加分啊
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

typedef HANDLE Semaphore; // 信号量的Windows原型
#define P(S) WaitForSingleObject(S, INFINITE) // 定义Windows下的P操作
#define V(S) ReleaseSemaphore(S, 1, NULL) // 定义Windows下的V操作

#define rate 1000

#define CONSUMER_NUM 10 /* 消费者个数 */
#define PRODUCER_NUM 10 /* 生产者个数 */
#define BUFFER_NUM 4 /* 缓冲区个数 */

char *thing[10] = {"猪脸", "牛鞭", "羊腰", "驴蹄", "狼心", "狗肺", "猴肝", "老虎屁股", "大象肚", "河马大肠"};

struct Buffer
{
int proct[BUFFER_NUM]; // 缓冲区
int start, end; // 两个指针
} g_buf;

Semaphore g_semBuffer, g_semProct, g_mutex;

// 消费者线程
DWORD WINAPI Consumer(LPVOID para)
{
// i表示第i个消费者
int i = *(int *)para;
int ptr; // 待消费的内容的指针

printf(" 猪头-%03d: 猪头我来啦!\n", i);

Sleep(300);
while (1)
{
printf(" 猪头-%03d: 我要吃.........!\n", i);
// 等待产品
P(g_semProct);

// 有产品,先锁住缓冲区 g_buf
P(g_mutex);

// 记录消费的物品
ptr = g_buf.start;

// 再移动缓冲区指针
g_buf.start = (g_buf.start+1)%BUFFER_NUM;

// 让其他消费者或生产者使用 g_buf
V(g_mutex);

printf(" 猪头-%03d: 我吃 buf[%d] = %s\n", i, ptr, thing[g_buf.proct[ptr]]);

Sleep(rate*rand()%10+110);

// 消费完毕,并释放一个缓冲
printf(" 猪头-%03d: 我爽了! buf[%d] = %s\n", i, ptr, thing[g_buf.proct[ptr]]);
V(g_semBuffer);
}
return 0;
}

// 生产者线程
DWORD WINAPI Procer(LPVOID para)
{
int i = *(int *)para - CONSUMER_NUM;
int ptr;
int data; // 产品

printf("工作狂-%03d: 我来啦!\n", i);

Sleep(300);
while (1)
{
printf("工作狂-%03d: 我干干干…………\n", i);
Sleep(rate*rand()%10+110);

data = rand()%10;
printf("工作狂-%03d: 搞出一个东西 data = %s!\n", i, thing[data]);
// 等待存放空间
P(g_semBuffer);

// 有地方,先锁住缓冲区 g_buf
P(g_mutex);

// 记录消费的物品
ptr = g_buf.end;

// 再移动缓冲区指针
g_buf.end = (g_buf.end+1)%BUFFER_NUM;

// 让其他消费者或生产者使用 g_buf
V(g_mutex);

printf("工作狂-%03d: 搁到 buf[%d] = %s\n", i, ptr, thing[data]);
g_buf.proct[ptr] = data;

Sleep(rate/2*rand()%10+110);

// 放好了完毕,释放一个产品
printf("工作狂-%03d: buf[%d] = %s 放好了,大家吃!\n", i, ptr, thing[g_buf.proct[ptr]]);
V(g_semProct);
}
return 0;
}

int main(int argc, char *argv[])
{
// 线程技术,前面为消费者线程,后面为生产者线程
HANDLE hThread[CONSUMER_NUM+PRODUCER_NUM]; // 线程计数

//srand(time());
DWORD tid;
int i=0;

// 初始化信号量
g_mutex = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "mutexOfConsumerAndProcer");
g_semBuffer = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "BufferSemaphone");
g_semProct = CreateSemaphore(NULL, 0, BUFFER_NUM, "ProctSemaphone");

if ( !g_semBuffer || !g_semProct || !g_mutex)
{
printf("Create Semaphone Error!\n");
return -1;
}

int totalThreads = CONSUMER_NUM+PRODUCER_NUM;
// 开启消费者线程
printf("先请猪头们上席!\n");
for (i=0; i<CONSUMER_NUM; i++)
{
hThread[i] = CreateThread(NULL, 0, Consumer, &i, 0, &tid);
if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);
}

printf("厨子们就位!\n");
for (; i<totalThreads; i++)
{
hThread[i] = CreateThread(NULL, 0, Procer, &i, 0, &tid);
if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);
}

// 生产者和消费者的执行
WaitForMultipleObjects(totalThreads, hThread, TRUE, INFINITE);
return 0;
}

2、c语言实例,linux线程同步的信号量方式 谢谢

这么高的悬赏,实例放后面。信号量(sem),如同进程一样,线程也可以通过信号量来实现通信,虽然是轻量级的。信号量函数的名字都以"sem_"打头。线程使用的基本信号量函数有四个。

     信号量初始化。
     int sem_init (sem_t *sem , int pshared, unsigned int value);
    这是对由sem指定的信号量进行初始化,设置好它的共享选项(linux 只支持为0,即表示它是当前进程的局部信号量),然后给它一个初始值VALUE。
    等待信号量。给信号量减1,然后等待直到信号量的值大于0。
    int sem_wait(sem_t *sem);
    释放信号量。信号量值加1。并通知其他等待线程。
    int sem_post(sem_t *sem);
    销毁信号量。我们用完信号量后都它进行清理。归还占有的一切资源。
    int sem_destroy(sem_t *sem);#include <stdlib.h>  
    #include <stdio.h>  
    #include <unistd.h>  
    #include <pthread.h>  
    #include <semaphore.h>  
    #include <errno.h>  
    #define return_if_fail(p) if((p) == 0){printf ("[%s]:func error!/n", __func__);return;}  
    typedef struct _PrivInfo  
    {  
        sem_t s1;  
        sem_t s2;  
        time_t end_time;  
    }PrivInfo;  
    static void info_init (PrivInfo* thiz);  
    static void info_destroy (PrivInfo* thiz);  
    static void* pthread_func_1 (PrivInfo* thiz);  
    static void* pthread_func_2 (PrivInfo* thiz);  
    int main (int argc, char** argv)  
    {  
        pthread_t pt_1 = 0;  
        pthread_t pt_2 = 0;  
        int ret = 0;  
        PrivInfo* thiz = NULL;  
        thiz = (PrivInfo* )malloc (sizeof (PrivInfo));  
        if (thiz == NULL)  
        {  
            printf ("[%s]: Failed to malloc priv./n");  
            return -1;  
        }  
        info_init (thiz);  
        ret = pthread_create (&pt_1, NULL, (void*)pthread_func_1, thiz);  
        if (ret != 0)  
        {  
            perror ("pthread_1_create:");  
        }  
        ret = pthread_create (&pt_2, NULL, (void*)pthread_func_2, thiz);  
        if (ret != 0)  
        {  
            perror ("pthread_2_create:");  
        }  
        pthread_join (pt_1, NULL);  
        pthread_join (pt_2, NULL);  
        info_destroy (thiz);  
        return 0;  
    }  
    static void info_init (PrivInfo* thiz)  
    {  
        return_if_fail (thiz != NULL);  
        thiz->end_time = time(NULL) + 10;  
        sem_init (&thiz->s1, 0, 1);  
        sem_init (&thiz->s2, 0, 0);  
        return;  
    }  
    static void info_destroy (PrivInfo* thiz)  
    {  
        return_if_fail (thiz != NULL);  
        sem_destroy (&thiz->s1);  
        sem_destroy (&thiz->s2);  
        free (thiz);  
        thiz = NULL;  
        return;  
    }  
    static void* pthread_func_1 (PrivInfo* thiz)  
    {  
        return_if_fail(thiz != NULL);  
        while (time(NULL) < thiz->end_time)  
        {  
            sem_wait (&thiz->s2);  
            printf ("pthread1: pthread1 get the lock./n");  
            sem_post (&thiz->s1);  
            printf ("pthread1: pthread1 unlock/n");  
            sleep (1);  
        }  
        return;  
    }  
    static void* pthread_func_2 (PrivInfo* thiz)  
    {  
        return_if_fail (thiz != NULL);  
        while (time (NULL) < thiz->end_time)  
        {  
            sem_wait (&thiz->s1);  
            printf ("pthread2: pthread2 get the unlock./n");  
            sem_post (&thiz->s2);  
            printf ("pthread2: pthread2 unlock./n");  
            sleep (1);  
        }  
        return;  
    }

3、C语言 static int sem_id = 0:什么意思

宣告一个静态变量, 预设为0.
该变量, 可视范围(可叫用的区块)不变, 生命周期直到程序结束.

4、急!LINUX下,GCC编译,原程序包含<semaphore.h>头文件,为什么编译时说sem_wait,sem_post等未定义的引用

编译时加上参数:-lpthread

要看报错的阶段,是在编译还是链接阶段.
如果编译时函数没有找到,那是头文件的问题,如果链接时未定义引用,那是c库的问题.
如果你的头文件都正常包含了,那可能你的c库没有使能semaphore的支持.

5、用C语言实现PV操作生产者消费者关系

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

typedef HANDLE Semaphore; // 信号量的Windows原型
#define P(S) WaitForSingleObject(S, INFINITE) // 定义Windows下的P操作
#define V(S) ReleaseSemaphore(S, 1, NULL) // 定义Windows下的V操作

#define rate 1000

#define CONSUMER_NUM 10 /* 消费者个数 */
#define PRODUCER_NUM 10 /* 生产者个数 */
#define BUFFER_NUM 4 /* 缓冲区个数 */

char *thing[10] = ;

struct Buffer
{
int proct[BUFFER_NUM]; // 缓冲区
int start, end; // 两个指针
} g_buf;

Semaphore g_semBuffer, g_semProct, g_mutex;

// 消费者线程
DWORD WINAPI Consumer(LPVOID para)
{
// i表示第i个消费者
int i = *(int *)para;
int ptr; // 待消费的内容的指针

printf(" 猪头-%03d: 猪头我来啦!\n", i);

Sleep(300);
while (1)
{
printf(" 猪头-%03d: 我要吃.........!\n", i);
// 等待产品
P(g_semProct);

// 有产品,先锁住缓冲区 g_buf
P(g_mutex);

// 记录消费的物品
ptr = g_buf.start;

// 再移动缓冲区指针
g_buf.start = (g_buf.start+1)%BUFFER_NUM;

// 让其他消费者或生产者使用 g_buf
V(g_mutex);

printf(" 猪头-%03d: 我吃 buf[%d] = %s\n", i, ptr, thing[g_buf.proct[ptr]]);

Sleep(rate*rand()%10+110);

// 消费完毕,并释放一个缓冲
printf(" 猪头-%03d: 我爽了! buf[%d] = %s\n", i, ptr, thing[g_buf.proct[ptr]]);
V(g_semBuffer);
}
return 0;
}

// 生产者线程
DWORD WINAPI Procer(LPVOID para)
{
int i = *(int *)para - CONSUMER_NUM;
int ptr;
int data; // 产品

printf("工作狂-%03d: 我来啦!\n", i);

Sleep(300);
while (1)
{
printf("工作狂-%03d: 我干干干…………\n", i);
Sleep(rate*rand()%10+110);

data = rand()%10;
printf("工作狂-%03d: 搞出一个东西 data = %s!\n", i, thing[data]);
// 等待存放空间
P(g_semBuffer);

// 有地方,先锁住缓冲区 g_buf
P(g_mutex);

// 记录消费的物品
ptr = g_buf.end;

// 再移动缓冲区指针
g_buf.end = (g_buf.end+1)%BUFFER_NUM;

// 让其他消费者或生产者使用 g_buf
V(g_mutex);

printf("工作狂-%03d: 搁到 buf[%d] = %s\n", i, ptr, thing[data]);
g_buf.proct[ptr] = data;

Sleep(rate/2*rand()%10+110);

// 放好了完毕,释放一个产品
printf("工作狂-%03d: buf[%d] = %s 放好了,大家吃!\n", i, ptr, thing[g_buf.proct[ptr]]);
V(g_semProct);
}
return 0;
}

int main(int argc, char *argv[])
{
// 线程技术,前面为消费者线程,后面为生产者线程
HANDLE hThread[CONSUMER_NUM+PRODUCER_NUM]; // 线程计数

//srand(time());
DWORD tid;
int i=0;

// 初始化信号量
g_mutex = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "mutexOfConsumerAndProcer");
g_semBuffer = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "BufferSemaphone");
g_semProct = CreateSemaphore(NULL, 0, BUFFER_NUM, "ProctSemaphone");

if ( !g_semBuffer || !g_semProct || !g_mutex)
{
printf("Create Semaphone Error!\n");
return -1;
}

int totalThreads = CONSUMER_NUM+PRODUCER_NUM;
// 开启消费者线程
printf("先请猪头们上席!\n");
for (i=0; i<CONSUMER_NUM; i++)
{
hThread[i] = CreateThread(NULL, 0, Consumer, &i, 0, &tid);
if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);
}

printf("厨子们就位!\n");
for (; i<totalThreads; i++)
{
hThread[i] = CreateThread(NULL, 0, Procer, &i, 0, &tid);
if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);
}

// 生产者和消费者的执行
WaitForMultipleObjects(totalThreads, hThread, TRUE, INFINITE);
return 0;
}

6、pv 原语实现生产者消费者问题,用C语言编程

下面是我本学期做过的一个课程设计
你可以参考一下,应该差不多

一、如何建立线程
用到的头文件
(a)pthread.h
(b)semaphore.h
(c) stdio.h
(d)string.h
定义线程标识
pthread_t
创建线程
pthread_create
对应了一个函数作为线程的程序段
注意的问题
要保证进程不结束(在创建线程后加死循环)
在线程中加入While(1)语句,也就是死循环,保证进程不结束。

二、控制线程并发的函数
sem_t:信号量的类型
sem_init:初始化信号量
sem_wait:相当于P操作
sem_post:相当于V操作

三、实现原形系统
父亲、母亲、儿子和女儿的题目:
桌上有一只盘子,每次只能放入一只水果。爸爸专放苹果,妈妈专放橘子,一个儿子专等吃盘子中的橘子,一个女儿专等吃盘子中的苹果。分别用P,V操作和管程实现

每个对应一个线程
pthread_t father; father进程
pthread_t mother; mother进程
pthread_t son; son进程
pthread_t daughter; daughter进程

盘子可以用一个变量表示
sem_t empty;

各线程不是只做一次,可以是无限或有限次循环
用While(1)控制各线程无限次循环

输出每次是那个线程执行的信息
printf("%s\n",(char *)arg);通过参数arg输出对应线程执行信息

编译方法
gcc hex.c -lpthread
生成默认的可执行文件a.out
输入./a.out命令运行
查看结果:程序连续运行显示出
father input an apple.
daughter get an apple.
mother input an orange.
son get an orange.
mother input an orange.
son get an orange.
………………..
四、程序源代码
#include <stdio.h>
#include<string.h>
#include <semaphore.h>
#include <pthread.h>
sem_t empty; //定义信号量
sem_t applefull;
sem_t orangefull;

void *procf(void *arg) //father线程
{
while(1){
sem_wait(&empty); //P操作
printf("%s\n",(char *)arg);
sem_post(&applefull); //V操作
sleep(7);
}

}
void *procm(void *arg) //mother线程
{
while(1){
sem_wait(&empty);
printf("%s\n",(char *)arg);
sem_post(&orangefull);
sleep(3);
}
}
void *procs(void *arg) //son线程
{
while(1){
sem_wait(&orangefull);
printf("%s\n",(char *)arg);
sem_post(&empty);
sleep(2);
}
}
void *procd(void *arg) //daughter线程
{
while(1){
sem_wait(&applefull);
printf("%s\n",(char *)arg);
sem_post(&empty);
sleep(5);
}

}

main()
{
pthread_t father; //定义线程
pthread_t mother;
pthread_t son;
pthread_t daughter;
sem_init(&empty, 0, 1); //信号量初始化
sem_init(&applefull, 0, 0);
sem_init(&orangefull, 0, 0);

pthread_create(&father,NULL,procf,"father input an apple."); //创建线程
pthread_create(&mother,NULL,procm,"mother input an orange.");
pthread_create(&daughter,NULL,procd,"daughter get an apple.");
pthread_create(&son,NULL,procs,"son get an orange.");

while(1){} //循环等待
}

7、c语言,做出pv操作

给你提供一个抄思路:参考操作系袭统课程的教材,分别单独编写 P、V 操作,设置一个信号量 sem,用于控制可用资源数目。这道题主要考的是操作系统的 P、V 操作的概念问题,C语言只是一个实现该功能的程序而已。

8、linux C编程 信号量sys/sem 有等待超时么

可以用semtimedop

9、c语言指令有哪些啊

你的意思是关键字吧。。。

auto :声明自动变量 一般不使用
double :声明双精度变量或函数
int: 声明整型变量或函数
struct:声明结构体变量或函数
break:跳出当前循环
else :条件语句否定分支(与 if 连用)
long :声明长整型变量或函数
switch :用于开关语句
case:开关语句分支
enum :声明枚举类型
register:声明积存器变量
typedef:用以给数据类型取别名(当然还有其他作用)
char :声明字符型变量或函数
extern:声明变量是在其他文件正声明(也可以看做是引用变量)
return :子程序返回语句(可以带参数,也看不带参数)
union:声明联合数据类型
const :声明只读变量
float:声明浮点型变量或函数
short :声明短整型变量或函数
unsigned:声明无符号类型变量或函数
continue:结束当前循环,开始下一轮循环
for:一种循环语句(可意会不可言传)
signed:生命有符号类型变量或函数
void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用)
default:开关语句中的“其他”分支
goto:无条件跳转语句
sizeof:计算数据类型长度
volatile:说明变量在程序执行中可被隐含地改变
do :循环语句的循环体
while :循环语句的循环条件
static :声明静态变量
if:条件语句

与c语言sem相关的知识