您的位置:

linuxc语言信号,C语言信号

本文目录一览:

C语言中信号问题

信号是程序执行过程中出现的异常情况。它可能是由程序中的错误造成的,例如引用内存中的一个非法地址;或者是由程序数据中的错误造成的,例如浮点数被0除;或者是由外部事件引发的,例如用户按了Ctrl+Break键。

你可以利用标准库函数signal()指定要对这些异常情况采取的处理措施(实施处理措施的函数被称为“信号处理函数”)。signal()的原型为:

#include signal.h

void(*signal(int hum,void(*func)(int)))(int);

如果定义一个typedef,理解起来就容易一些了。下面给出的sigHandler_t类型是指向一个程序的指针,该函数有一个int类型的参数,并且返回一个void类型:

typedef void(*sigHandler_t)(int);

sigHandler_t signal(int num , sigHandler_t func);

signal()有两个参数,分别为int类型和sigHandler_t类型,其返回值为sigHandler_t类型。以func参数形式传递给signal()的那个函数将成为第num号异常情况的新的信号处理函数。signal()的返回值是信号hum原来的信号处理函数。在设置了一个暂时的信号处理函数之后,你可以利用该值恢复程序先前的行为。num的可能值依赖于系统,并且在signal.h中列出。func的可能值可以是你的程序中的任意函数,或者是SIG_DFL和SLG_IGN这两个特别定义的值之一。SIG_DFL是指系统的缺省处理措施,通常是暂停执行程序;SIG_IGN表示信号将被忽略。

请教一个Linux下C语言的进程间的信号问题

linux中的进程通信分为三个部分:低级通信,管道通信和进程间通信IPC(inter process communication)。linux的低级通信主要用来传递进程的控制信号——文件锁和软中断信号机制。linux的进程间通信IPC有三个部分——①信号量,②共享内存和③消息队列。以下是我编写的linux进程通信的C语言实现代码。操作系统为redhat9.0,编辑器为vi,编译器采用gcc。下面所有实现代码均已经通过测试,运行无误。

一.低级通信--信号通信

signal.c

#include

#include

#include

/*捕捉到信号sig之后,执行预先预定的动作函数*/

void sig_alarm(int sig)

{

printf("---the signal received is %d. /n", sig);

signal(SIGINT, SIG_DFL); //SIGINT终端中断信号,SIG_DFL:恢复默认行为,SIN_IGN:忽略信号

}

int main()

{

signal(SIGINT, sig_alarm);//捕捉终端中断信号

while(1)

{

printf("waiting here!/n");

sleep(1);

}

return 0;

}

二.管道通信

pipe.c

#include

#define BUFFER_SIZE 30

int main()

{

int x;

int fd[2];

char buf[BUFFER_SIZE];

char s[BUFFER_SIZE];

pipe(fd);//创建管道

while((x=fork())==-1);//创建管道失败时,进入循环

/*进入子进程,子进程向管道中写入一个字符串*/

if(x==0)

{

sprintf(buf,"This is an example of pipe!/n");

write(fd[1],buf,BUFFER_SIZE);

exit(0);

}

/*进入父进程,父进程从管道的另一端读出刚才写入的字符串*/

else

{

wait(0);//等待子进程结束

read(fd[0],s,BUFFER_SIZE);//读出字符串,并将其储存在char s[]中

printf("%s",s);//打印字符串

}

return 0;

}

三.进程间通信——IPC

①信号量通信

sem.c

#include

#include

#include

#include types.h

#include ipc.h

#include sem.h

/*联合体变量*/

union semun

{

int val; //信号量初始值

struct semid_ds *buf;

unsigned short int *array;

struct seminfo *__buf;

};

/*函数声明,信号量定义*/

static int set_semvalue(void); //设置信号量

static void del_semvalue(void);//删除信号量

static int semaphore_p(void); //执行P操作

static int semaphore_v(void); //执行V操作

static int sem_id; //信号量标识符

int main(int argc, char *argv[])

{

int i;

int pause_time;

char op_char = 'O';

srand((unsigned int)getpid());

sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);//创建一个信号量,IPC_CREAT表示创建一个新的信号量

/*如果有参数,设置信号量,修改字符*/

if (argc 1)

{

if (!set_semvalue())

{

fprintf(stderr, "Failed to initialize semaphore/n");

exit(EXIT_FAILURE);

}

op_char = 'X';

sleep(5);

}

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

{

/*执行P操作*/

if (!semaphore_p())

exit(EXIT_FAILURE);

printf("%c", op_char);

fflush(stdout);

pause_time = rand() % 3;

sleep(pause_time);

printf("%c", op_char);

fflush(stdout);

/*执行V操作*/

if (!semaphore_v())

exit(EXIT_FAILURE);

pause_time = rand() % 2;

sleep(pause_time);

}

printf("/n%d - finished/n", getpid());

if (argc 1)

{

sleep(10);

del_semvalue(); //删除信号量

}

exit(EXIT_SUCCESS);

}

/*设置信号量*/

static int set_semvalue(void)

{

union semun sem_union;

sem_union.val = 1;

if (semctl(sem_id, 0, SETVAL, sem_union) == -1)

return(0);

return(1);

}

/*删除信号量*/

static void del_semvalue(void)

{

union semun sem_union;

if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)

fprintf(stderr, "Failed to delete semaphore/n");

}

/*执行P操作*/

static int semaphore_p(void)

{

struct sembuf sem_b;

sem_b.sem_num = 0;

sem_b.sem_op = -1; /* P() */

sem_b.sem_flg = SEM_UNDO;

if (semop(sem_id, sem_b, 1) == -1)

{

fprintf(stderr, "semaphore_p failed/n");

return(0);

}

return(1);

}

/*执行V操作*/

static int semaphore_v(void)

{

struct sembuf sem_b;

sem_b.sem_num = 0;

sem_b.sem_op = 1; /* V() */

sem_b.sem_flg = SEM_UNDO;

if (semop(sem_id, sem_b, 1) == -1)

{

fprintf(stderr, "semaphore_v failed/n");

return(0);

}

return(1);

}

②消息队列通信

send.c

#include

#include

#include

#include

#include

#include types.h

#include ipc.h

#include msg.h

#define MAX_TEXT 512

/*用于消息收发的结构体--my_msg_type:消息类型,some_text:消息正文*/

struct my_msg_st

{

long int my_msg_type;

char some_text[MAX_TEXT];

};

int main()

{

int running = 1;//程序运行标识符

struct my_msg_st some_data;

int msgid;//消息队列标识符

char buffer[BUFSIZ];

/*创建与接受者相同的消息队列*/

msgid = msgget((key_t)1234, 0666 | IPC_CREAT);

if (msgid == -1)

{

fprintf(stderr, "msgget failed with error: %d/n", errno);

exit(EXIT_FAILURE);

}

/*向消息队列中发送消息*/

while(running)

{

printf("Enter some text: ");

fgets(buffer, BUFSIZ, stdin);

some_data.my_msg_type = 1;

strcpy(some_data.some_text, buffer);

if (msgsnd(msgid, (void *)some_data, MAX_TEXT, 0) == -1)

{

fprintf(stderr, "msgsnd failed/n");

exit(EXIT_FAILURE);

}

if (strncmp(buffer, "end", 3) == 0)

{

running = 0;

}

}

exit(EXIT_SUCCESS);

}

receive.c

#include

#include

#include

#include

#include

#include types.h

#include ipc.h

#include msg.h

/*用于消息收发的结构体--my_msg_type:消息类型,some_text:消息正文*/

struct my_msg_st

{

long int my_msg_type;

char some_text[BUFSIZ];

};

int main()

{

int running = 1;//程序运行标识符

int msgid; //消息队列标识符

struct my_msg_st some_data;

long int msg_to_receive = 0;//接收消息的类型--0表示msgid队列上的第一个消息

/*创建消息队列*/

msgid = msgget((key_t)1234, 0666 | IPC_CREAT);

if (msgid == -1)

{

fprintf(stderr, "msgget failed with error: %d/n", errno);

exit(EXIT_FAILURE);

}

/*接收消息*/

while(running)

{

if (msgrcv(msgid, (void *)some_data, BUFSIZ,msg_to_receive, 0) == -1)

{

fprintf(stderr, "msgrcv failed with error: %d/n", errno);

exit(EXIT_FAILURE);

}

printf("You wrote: %s", some_data.some_text);

if (strncmp(some_data.some_text, "end", 3) == 0)

{

running = 0;

}

}

/*删除消息队列*/

if (msgctl(msgid, IPC_RMID, 0) == -1)

{

fprintf(stderr, "msgctl(IPC_RMID) failed/n");

exit(EXIT_FAILURE);

}

exit(EXIT_SUCCESS);

}

③共享内存通信

share.h

#define TEXT_SZ 2048 //申请共享内存大小

struct shared_use_st

{

int written_by_you; //written_by_you为1时表示有数据写入,为0时表示数据已经被消费者提走

char some_text[TEXT_SZ];

};

producer.c

#include

#include

#include

#include

#include types.h

#include ipc.h

#include shm.h

#include "share.h"

int main()

{

int running = 1; //程序运行标志位

void *shared_memory = (void *)0;

struct shared_use_st *shared_stuff;

char buffer[BUFSIZ];

int shmid; //共享内存标识符

/*创建共享内存*/

shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);

if (shmid == -1)

{

fprintf(stderr, "shmget failed/n");

exit(EXIT_FAILURE);

}

/*将共享内存连接到一个进程的地址空间中*/

shared_memory = shmat(shmid, (void *)0, 0);//指向共享内存第一个字节的指针

if (shared_memory == (void *)-1)

{

fprintf(stderr, "shmat failed/n");

exit(EXIT_FAILURE);

}

printf("Memory attached at %X/n", (int)shared_memory);

shared_stuff = (struct shared_use_st *)shared_memory;

/*生产者写入数据*/

while(running)

{

while(shared_stuff-written_by_you == 1)

{

sleep(1);

printf("waiting for client.../n");

}

printf("Enter some text: ");

fgets(buffer, BUFSIZ, stdin);

strncpy(shared_stuff-some_text, buffer, TEXT_SZ);

shared_stuff-written_by_you = 1;

if (strncmp(buffer, "end", 3) == 0)

{

running = 0;

}

}

/*该函数用来将共享内存从当前进程中分离,仅使得当前进程不再能使用该共享内存*/

if (shmdt(shared_memory) == -1)

{

fprintf(stderr, "shmdt failed/n");

exit(EXIT_FAILURE);

}

printf("producer exit./n");

exit(EXIT_SUCCESS);

}

customer.c

#include

#include

#include

#include

#include types.h

#include ipc.h

#include shm.h

#include "share.h"

int main()

{

int running = 1;//程序运行标志位

void *shared_memory = (void *)0;

struct shared_use_st *shared_stuff;

int shmid; //共享内存标识符

srand((unsigned int)getpid());

/*创建共享内存*/

shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);

if (shmid == -1)

{

fprintf(stderr, "shmget failed/n");

exit(EXIT_FAILURE);

}

/*将共享内存连接到一个进程的地址空间中*/

shared_memory = shmat(shmid, (void *)0, 0);//指向共享内存第一个字节的指针

if (shared_memory == (void *)-1)

{

fprintf(stderr, "shmat failed/n");

exit(EXIT_FAILURE);

}

printf("Memory attached at %X/n", (int)shared_memory);

shared_stuff = (struct shared_use_st *)shared_memory;

shared_stuff-written_by_you = 0;

/*消费者读取数据*/

while(running)

{

if (shared_stuff-written_by_you)

{

printf("You wrote: %s", shared_stuff-some_text);

sleep( rand() % 4 );

shared_stuff-written_by_you = 0;

if (strncmp(shared_stuff-some_text, "end", 3) == 0)

{

running = 0;

}

}

}

/*该函数用来将共享内存从当前进程中分离,仅使得当前进程不再能使用该共享内存*/

if (shmdt(shared_memory) == -1)

{

fprintf(stderr, "shmdt failed/n");

exit(EXIT_FAILURE);

}

/*将共享内存删除,所有进程均不能再访问该共享内存*/

if (shmctl(shmid, IPC_RMID, 0) == -1)

{

fprintf(stderr, "shmctl(IPC_RMID) failed/n");

exit(EXIT_FAILURE);

}

exit(EXIT_SUCCESS);

}

摘自:

linux c开发: 在程序退出时进行处理

有时候,希望程序退出时能进行一些处理,比如保存状态,释放一些资源。c语言开发的linux程序,有可能正常退出(exit),有可能异常crash,而异常crash可能是响应了某信号的默认处理。这里总结一下这些情况,如何获取一个统一的退出处理的点,说白了就是写一个回调函数,让他在程序正常或异常退出时调用。

这个例子里面其实是将异常退出处理和正常退出处理结合起来了。对于SIGTERM(即kill进程)和SIGINT(即ctrl-c结束前台进程),我们当做是正常退出,在其信号处理函数里面,直接调用了exit(0),而exit(0)又会被server_on_exit捕获到。对于异常退出也是类似,只是调用了exit(-1)表示是异常的。同时异常退出我们会打印出当前的进程堆栈信息,server_backtrace的实现下一篇再说。另外注意的是SIGKILL信号是无法捕获的。而调用abort导致的退出,也是通过SIGABRT信号捕获到进行处理了。其他几种异常退出的信号也是比较常见,一并捕获到进行处理。这样对于异常退出,我们即可统一的log堆栈信息,又可直接继续正常退出时的处理流程了。

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;  

    }

Linux 环境下的C语言, 关于 kill 发送信号和 signal() 函数, 具体问题在以下代码的注释处

pause()会令目前的进程暂停(进入睡眠状态), 直到被信号(signal)所中断。

当50信号触动了,pause将退出睡眠状态,执行printf和return

linux中c语言有关信号的程序

简单处理了一下,希望对你有帮助

#define err_sys( str ) printf("error:%s\n" , str )

static void sig_int(int signo)

{

struct tms timebuf;

int wallclock=times(timebuf);

fprintf(stderr,"clock ticks since system startup are %d,\n",wallclock);

}

static void sig_term(int signo)

{

struct tms timebuf;

int wallclock=times(timebuf);

fprintf(stderr,"clock ticks since system start are %d,\n",wallclock);

exit(0); //终止程序

}

static void sig_alrm(int signo)

{

static int times=1;

alarm(0);//输出时,不再计时

printf("time:%d\n" , times*10 );

times++ ;

alarm(10); //重新开始计时

}

int main()

{

if (signal(SIGINT,sig_int)==SIG_ERR)

err_sys("can't catch SIGINT");

if (signal(SIGTERM,sig_term)==SIG_ERR)

err_sys("can't catch SIGTERM");

alarm(10); //开始计时

if (signal(SIGALRM,sig_alrm)==SIG_ERR)

err_sys("can't catch SIGALRM");

while(1) ; //等待在这里

return(0);

}