導航:首頁 > 網路營銷 > 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相關的知識