C语言的信号触发

目录

一、 信号触发

头文件

例子


一、 信号触发

头文件

#include <semaphore.h>

函数原型

sem_init

/**
 * 初始化信号量
 * sem: 是一个匿名的信号量
 * pshared: 指明是由进程内共享还是线程之间共享。
 *      如果是0表示: 那么信号量将被进程内的线程共享,并且应该放置在这个进程的所有线程都可见的地址上(如全局变量,或者堆上动态分配的变量),
 *      如果是非0值表示: 那么信号量将在进程之间共享,并且应该定位共享内存区域(见 shm_open(3)、mmap(2) 和 shmget(2))。
 *          因为通过 fork(2) 创建的孩子继承其父亲的内存映射,因此它也可以见到这个信号量。
 *          所有可以访问共享内存区域的进程都可以用 sem_post(3)、sem_wait(3) 等等操作信号量。初始化一个已经初始的信号量其结果未定义
 * value: 指定信号量的初始值
 */
int sem_init(sem_t* sem, int pshared, unsigned int value);

返回值

sem_init() 成功时返回 0;错误时,返回 -1,并把 errno 设置为合适的值。

sem_wait

/**
 * 减小(锁定)由sem指定的信号量的值.
 * sem: 是一个匿名的信号量
 */
int sem_wait(sem_t* sem);

返回值

sem_wait()成功返回0,错误的话信号量的值不改动,返回-1

sem_post

/**
 * 增加(锁定)由sem指定的信号量的值.
 * sem: 是一个匿名的信号量
 */
int sem_post(sem_t* sem);

返回值

sem_wait()成功返回0,错误的话信号量的值不改动,返回-1

sem_destroy

/**
 * 清理用完的信号.
 * sem: 是一个匿名的信号量
 */
int sem_destroy(sem_t* sem);

返回值

sem_destroy()成功返回0,错误返回-1

例子

/**
 * 俩个线程通过信号交替输出组合成Hello world!
 */
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
sem_t blank_number, product_number;
void *producer(int* num)
{
    int i;
    for (i = 0; i < *num; i++) {
        printf("Hello ");
        sem_post(&product_number);	// 信号触发
        sem_wait(&blank_number);	// 等待信号触发
    }
}
void *consumer(int* num)
{
    int i;
	for (i = 0; i < *num; i++) {
		sem_wait(&product_number);	// 等待信号触发
        printf("world! ");
        sem_post(&blank_number);	// 信号触发
    }
}
int main(int argc, char *argv[])
{
    int num = 5;
	pthread_t pid, cid;

	// 触发信号
	sem_init(&blank_number, 0, 0);
	sem_init(&product_number, 0, 0);

	pthread_create(&pid, NULL, producer, (void *)&num);
	pthread_create(&cid, NULL, consumer, (void *)&num);


	pthread_join(pid, NULL);
	pthread_join(cid, NULL);

	// 销毁信号
	sem_destroy(&blank_number);
	sem_destroy(&product_number);
	return 0;
}

C语言支持信号处理功能,可以通过相应的库函数和系统调用来实现信号发生器。 首先,我们需要使用signal()函数来注册信号处理函数。例如,可以使用以下代码将Ctrl+C信号(SIGINT)注册为自定义的处理函数: ```c #include <stdio.h> #include <signal.h> void sigHandler(int signum) { printf("接收到信号:%d\n", signum); } int main() { signal(SIGINT, sigHandler); //注册信号处理函数 while(1) { //无限循环,等待信号 } return 0; } ``` 在上述代码中,我们定义了一个名为sigHandler()的信号处理函数,用于在接收到SIGINT信号时打印相关信息。在main()函数中,我们使用signal()函数将SIGINT信号和sigHandler()函数进行绑定。之后,进入一个无限循环,等待信号的到来。 接下来,我们可以使用raise()函数来模拟信号的发送。例如,我们可以在程序中的任意位置调用raise(SIGINT)来发送SIGINT信号,如下所示: ```c #include <stdio.h> #include <signal.h> void sigHandler(int signum) { printf("接收到信号:%d\n", signum); } int main() { signal(SIGINT, sigHandler); //注册信号处理函数 printf("程序开始\n"); raise(SIGINT); //发送SIGINT信号 printf("程序结束\n"); return 0; } ``` 在上述代码中,我们在程序开始和结束处分别打印相关信息,并在程序中间位置调用raise(SIGINT)来发送SIGINT信号。当接收到信号时,将会触发sigHandler()函数,打印相关信息。 这样,我们就实现了一个简单的C语言信号发生器。当程序运行时,我们可以手动发送信号或通过系统调用来触发信号处理函数的执行。这在一些特定的应用场景中非常有用,比如在收到某个特定信号触发一些特定操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值