linux线程间同步信号量semp性能,自己实现的一个简单的信号量机制(用于线程同步)...

根据信号量的原理,自己写了一个简单的信号量类,用于线程同步,以下代码在Linux下调试通过

#include

#include

#include

using namespace std;

class Sem

{

public:

Sem(int &initValue){ semValue = initValue;}

void WaitSem()

{

//信号量大于0,将信号量减1

if(semValue > 0)

{

semValue--;

}

else

{

//信号量 <= 0,则阻塞线程,直到信号量大于0

while(1)

{

if(semValue > 0)

{

semValue--;

break;

}

else

continue;

}

}

}

void PostSem()

{         //信号量加1

semValue++;

}

private:

int semValue;

};

int semp =0; //信号量初始值

Sem sem(semp);

int ncount = 0;

int threadnum = 0;

void *count1(void* arg)

{

sem.WaitSem();

threadnum++;

char name[20];

sprintf(name, "thread %d", threadnum);

cout << name << " start!" << endl;

for(int i = 0; i < 5; i++)

{

ncount += 3;

}

sleep(1);

cout << name << " ncount: " << ncount << endl;

sem.PostSem();

return (void*)0;

}

int main()

{

pthread_t tid[10];

cout << "start create thread!" << endl;

sem.PostSem();

for(int i = 0; i < 10; i++)

{

pthread_create(&tid[i], NULL, count1, NULL);

}

for(int i = 0; i < 10; i++)

{

pthread_join(tid[i], NULL);

}

sleep(2);

cout << "main thread" << endl;

return 0;

}

程序的运行结果如下

start create thread!

thread 1 start!

thread 1 ncount: 15

thread 2 start!

thread 2 ncount: 30

thread 3 start!

thread 3 ncount: 45

thread 4 start!

thread 4 ncount: 60

thread 5 start!

thread 5 ncount: 75

thread 6 start!

thread 6 ncount: 90

thread 7 start!

thread 7 ncount: 105

thread 8 start!

thread 8 ncount: 120

thread 9 start!

thread 9 ncount: 135

thread 10 start!

thread 10 ncount: 150

main thread

在一个线程对ncount进行操作的时候,其他线程被阻塞,因此打印出来的ncount依次累加15.

注释掉 sem.WaitSem()和sem.PostSem()之后,程序运行结果如下

start create thread!

thread 1 start!

thread 2 start!

thread 3 start!

thread 4 start!

thread 5 start!

thread 6 start!

thread 7 start!

thread 8 start!

thread 9 start!

thread 10 start!

thread 1 ncount: 150

thread 2 ncount: 150

thread 3 ncount: 150

thread 4 ncount: 150

thread 5 ncount: 150

thread 6 ncount: 150

thread 7 ncount: 150

thread 8 ncount: 150

thread 9 ncount: 150

thread 10 ncount: 150

main thread

因为在1秒钟里,10个线程都对ncount加了15,因此大于出来的ncount为150

此信号量类实现了简单的线程同步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于信号量和wait、signal函数实现的数据库读写限制程序示例: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/sem.h> #include <sys/shm.h> #define SHM_KEY 0x1234 // 共享内存的key #define SEM_KEY 0x5678 // 信号量的key #define BUFF_SIZE 1024 // 数据库缓冲区大小 union semun { int val; // value for SETVAL struct semid_ds *buf; // buffer for IPC_STAT & IPC_SET unsigned short *array; // array for GETALL & SETALL struct seminfo *__buf; // buffer for IPC_INFO }; // 定义共享内存结构体 typedef struct { char buffer[BUFF_SIZE]; // 数据库缓冲区 } ShmData; // 初始化信号量 int semInit(int semid, int value) { union semun sem_union; sem_union.val = value; return semctl(semid, 0, SETVAL, sem_union); } // P操作 int semP(int semid) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; return semop(semid, &sem_b, 1); } // V操作 int semV(int semid) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; return semop(semid, &sem_b, 1); } // 数据库读进程 void dbReadProc(int semid, ShmData *shm) { while (1) { semP(semid); // 请求访问数据库 printf("Reading data from database: %s\n", shm->buffer); sleep(1); // 模拟读取数据的耗时 semV(semid); // 释放数据库 } } // 数据库写进程 void dbWriteProc(int semid, ShmData *shm) { while (1) { semP(semid); // 请求访问数据库 printf("Writing data to database...\n"); fgets(shm->buffer, BUFF_SIZE, stdin); // 从标准输入中读取数据 sleep(1); // 模拟写入数据的耗时 semV(semid); // 释放数据库 } } int main() { // 创建共享内存 int shmid = shmget(SHM_KEY, sizeof(ShmData), 0666 | IPC_CREAT); if (shmid == -1) { perror("shmget"); exit(EXIT_FAILURE); } // 连接共享内存 ShmData *shm = (ShmData *)shmat(shmid, NULL, 0); if (shm == (void *)-1) { perror("shmat"); exit(EXIT_FAILURE); } // 创建信号量 int semid = semget(SEM_KEY, 1, 0666 | IPC_CREAT); if (semid == -1) { perror("semget"); exit(EXIT_FAILURE); } // 初始化信号量 semInit(semid, 1); // 初始值为1,表示允许读和写 // 创建数据库读进程和写进程 pid_t pid; if ((pid = fork()) == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid == 0) { // 子进程执行读进程 dbReadProc(semid, shm); } else { // 父进程执行写进程 dbWriteProc(semid, shm); } // 等待子进程结束 if (waitpid(pid, NULL, 0) == -1) { perror("waitpid"); exit(EXIT_FAILURE); } // 删除共享内存和信号量 if (shmctl(shmid, IPC_RMID, 0) == -1) { perror("shmctl"); exit(EXIT_FAILURE); } if (semctl(semid, 0, IPC_RMID) == -1) { perror("semctl"); exit(EXIT_FAILURE); } return 0; } ``` 在该示例程序中,我们使用了共享内存来存储数据库缓冲区,利用信号量实现读写操作的并发控制。其中,P操作用来请求访问数据库,V操作用来释放数据库。读进程和写进程在访问数据库之前都需要执行P操作,然后在访问完成后执行V操作。在写进程访问数据库期,读进程会一直被阻塞,直到写进程释放数据库。这样就保证了对数据库读写操作的限制条件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值