1-4节linux系统编程——进程通信信号和创建线程

通信信号

信号:一种异步通信机制
系统支持的信号都有默认的处理方式
常用的信号及其处理:SIGINT | SIGQUIT | SIGALRM | SIGCHLD |
常用信号及其处理方式:默认处理,忽略,自定义信号处理函数
注意:信号处理函数中不要做耗时的操作
注册信号处理函数:signal , sigaction
发送信号:kill , 组合键

线程创建和调度

线程是程序执行的某一条指令流的影像
线程函数:用于提供线程执行的指令(代码)
线程库:pthread
线程的创建:pthread_create
线程等待获取线程返回值:pthread_join
获取线程自身的线程ID:pthread_self
判断是否是同一个线程:pthread_equal
取消指定线程:pthread_cancel

2)进程通信

进程通信是进程之间相互通信或操作的一种方式
信号机制是异步的
信号依靠值来区分

2.1)当信号发生时,用户可以要求进程以下列3种方式之一对信号做出响应。

1、 捕捉信号:对于要捕捉的信号,可以为其指定信号处理函数,信号发生时该函数自动被调用,在该函数内部实现对该信号的处理。
2、 忽略信号:大多数信号都可使用这种方式进行处理,但是SIGKILL和SIGSTOP这两个信号不能被忽略,同时这两个信号也不能被捕获和阻塞。此外,如果忽略某某些由硬件异常产生的信号(如非法存储访问或除以0),则进程的行为是不可预测的。
3、 按照系统默认方式处理。大部分信号的默认操作是终止进程,且所有的实时信号的默认动作都是终止进程。

2.2)信号的优先级

信号实质上是软中断,中断有优先级,信号也有优先级。如果一个进程有多个未决信号,则对于同一个未决的实时信号,内核将按照发送的顺序来递送信号。如果存在多个未决信号,则值(或者说编号)越小的越先被递送。如果即存在不可靠信号,又存在可靠信号(实时信号),虽然POSIX对这一情况没有明确规定,但Linux系统和大多数遵循POSIX标准的操作系统一样,将优先递送不可靠信号。

2.3)SIG信号

信号的值定义在signal.h中,在Linux中没有16和32这两个信号。上面信号的含义如下:

(1) SIGHUP:当用户退出Shell时,由该Shell启的发所有进程都退接收到这个信号,默认动作为终止进程。
(2) SIGINT:用户按下组合键时,用户端时向正在运行中的由该终端启动的程序发出此信号。默认动作为终止进程。
(3) SIGQUIT:当用户按下组合键时产生该信号,用户终端向正在运行中的由该终端启动的程序发出此信号。默认动作为终止进程并产生core文件。
(4) SIGILL :CPU检测到某进程执行了非法指令。默认动作为终止进程并产生core文件。
(5) SIGTRAP:该信号由断点指令或其他trap指令产生。默认动作为终止进程并产生core文件。
(6) SIGABRT:调用abort函数时产生该信号。默认动作为终止进程并产生core文件。
(7) SIGBUS:非法访问内存地址,包括内存地址对齐(alignment)出错,默认动作为终止进程并产生core文件。
(8) SIGFPE:在发生致命的算术错误时产生。不仅包括浮点运行错误,还包括溢出及除数为0等所有的算术错误。默认动作为终止进程并产生core文件。
(9) SIGKILL:无条件终止进程。本信号不能被忽略、处理和阻塞。默认动作为终止进程。它向系统管理员提供了一种可以杀死任何进程的方法。
(10) SIGUSR1:用户定义的信号,即程序可以在程序中定义并使用该信号。默认动作为终止进程。
(11) SIGSEGV:指示进程进行了无效的内存访问。默认动作为终止进程并使用该信号。默认动作为终止进程。
(12) SIGUSR2:这是另外一个用户定义信号,程序员可以在程序中定义并使用该信号。默认动作为终止进程。
(13) SIGPIPE:Broken pipe:向一个没有读端的管道写数据。默认动作为终止进程。
(14) SIGALRM:定时器超时,超时的时间由系统调用alarm设置。默认动作为终止进程。
(15) SIGTERM:程序结束(terminate)信号,与SIGKILL不同的是,该信号可以被阻塞和处理。通常用来要求程序正常退出。执行Shell命令kill时,缺少产生这个信号。默认动作为终止进程。
(16) SIGCHLD:子程序结束时,父进程会收到这个信号。默认动作为忽略该信号。
(17) SIGCONT:让一个暂停的进程继续执行。
(18) SIGSTOP:停止(stopped)进程的执行。注意它和SIGTERM以及SIGINT的区别:该进程还未结束,只是暂停执行。本信号不能被忽略、处理和阻塞。默认作为暂停进程。
(19) SIGTSTP:停止进程的动作,但该信号可以被处理和忽略。按下组合键时发出该信号。默认动作为暂停进程。
(20) SIGTTIN:当后台进程要从用户终端读数据时,该终端中的所有进程会收到SIGTTIN信号。默认动作为暂停进程。
(21) SIGTTOU:该信号类似于SIGTIN,在后台进程要向终端输出数据时产生。默认动作为暂停进程。
(22) SIGURG:套接字(socket)上有紧急数据时,向当前正在运行的进程发出此信号,报告有紧急数据到达。默认动作为忽略该信号。
(23) SIGXCPU:进程执行时间超过了分配给该进程的CPU时间,系统产生该信号并发送给该进程。默认动作为终止进程。
(24) SIGXFSZ:超过文件最大长度的限制。默认动作为yl终止进程并产生core文件。
(25) SIGVTALRM:虚拟时钟超时时产生该信号。类似于SIGALRM,但是它只计算该进程占有用的CPU时间。默认动作为终止进程。
(26) SIGPROF:类似于SIGVTALRM,它不仅包括该进程占用的CPU时间还抱括执行系统调用的时间。默认动作为终止进程。
(27) SIGWINCH:窗口大小改变时发出。默认动作为忽略该信号。
(28) SIGIO:此信号向进程指示发出一个异步IO事件。默认动作为忽略。
(29) SIGPWR:关机。默认动作为终止进程。
(30) SIGRTMIN~SIGRTMAX:Linux的实时信号,它没有固定的含义(或者说可以由用户自由使用)。注意,Linux线程机制使用了前3个实时信号。所有的实时信号的默认动作都是终止进程

3)线程

了解 C10K问题
一条进程带一万条线程连接
解决方案
解决这一问题,主要思路有两个:
每个进程/线程处理一个连接
每个进程/线程同时处理多个连接(IO多路复用)
这些操作系统提供的功能就是为了解决C10K问题:FreeBSD推出了kqueue,Linux推出了epoll,Windows推出了IOCP,Solaris推出了/dev/poll。

了解两个网站
stackoverflow
segmentfault

进程控制块 PCB区
栈区
堆区(堆区和栈区相向增长)
数据区(全局变量)(多线程共享数据区)
文本区

4)pthread族函数

4.1)创建线程

pthread_create
pthread头文件
#include <pthread.h>
参数
int pthread_create ( pthread_t *thread, const pthread_attr_t *attr,void (start_routine) (void *), void *arg );
Compile and link with -pthread.
编译时加上 -lpthread 或 -pthread

4.2)pthread_join
int pthread_join(pthread_t thread, void **retval);

//函数pthread_join用来等待一个线程的结束,线程间同步的操作

4.3)pthread_exit
  void pthread_exit(void *retval);

//线程通过调用pthread_exit函数终止执行,就如同进程在结束时调用exit函数一样。这个函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。

4.4)pthread_cancel

是计算机语言,它发送终止信号给thread线程,如果成功则返回0,否则为非0值

4.6)pthread_self

pthread_self 是一种函数,功能是获得线程自身的ID

4.7)pthread_cond_wait

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起

程序

信号处理函数

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<time.h>

void sig_handle(int signo)
{
    switch(signo)
    {
        case SIGINT:
            printf("%d",getpid());
            break;
    }
}

int main (int argc ,char *argv[])
    {
    pid_t pid;
    signal(SIGINT , SIG_ING);//忽略信号
    signal(SIGINT, sig_handle);//显示信号
    signal(SIGINT, SIG_DFT);//默认信号

    pid = fork() ;

    while(1)
    {
        sleep(2);
        printf("befor \n");
    }

    return 0 ;
}

父子进程信号通讯

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
//练习2:创建一个子进程,子进程进入一个无限的循环,模拟一秒从数据中心取一个数据并处理的
//过程,直到子进程收到父进程发送过来的SIGUSR1信号,打印子进程pid,并退出
//父进程:创建子进程之后,循环等待信号的到达,当收到SIGINT(由组合键ctrl+c模拟)信号
//之后,向子进程发送一个SIGUSR1信号

pid_t pid;

void parent_sig_handler(int signo);
void child_sig_handler(int signo);

int main (int argc , char *argv[])
{
signal(SIGINT , parent_sig_handler);//显示父程序的信号
if((pid = fork()) == 0)
{
        while(1)
        {
        int client_id = 0;
        signal(SIGINT,SIG_IGN);     //忽略信号
        signal(SIGINT ,child_sig_handler ); //显示子程序的信号
            while(1)
            {
            client_id=rand()%100+1;
            printf("client in %d\n",client_id);
            sleep(1);
            printf("client out %d\n",client_id);
            }
        }
}
else if(pid > 0)
    {
    while(1);
    }

return 0;
}
//父程序
void parent_sig_handler(int signo)
{
switch(signo)
    {
    case SIGCHLD:
        wait(NULL);
        break;
    case SIGINT :
        //kill函数向指定 进程发送指定信号值
        //注意,信号发送无法传递数据
        kill (pid, SIGUSR1);
        break;
    default:
        break;
    }
}
//子程序
void child_sig_handler(int signo)
{
if(signo == SIGUSR1)
    {
    printf(child pid"%d\n",getpid() );
    exit(0);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容