Linux進程、線程、核心操作函數__Oracle

來源:互聯網
上載者:User
進程

1.        替換進程鏡像

#include <unistd.h>

       extern char **environ;

       int execl(const char *path, const char*arg, ..., (char*)0);

       int execlp(const char *file, const char*arg, ..., (char*)0);

       int execle(const char *path, const char*arg, ..., char * const envp[]);

       int execv(const char *path, char *constargv[]);

       int execvp(const char *file, char *constargv[]);

           int execve(const char *file, char *const argv[], char *const envp[]);

1)        execl、execlp、execle參數可變,以null 指標結束;execv、execvp第二個參數為一字串數組。

2)        函數會把argv參數傳遞給main函數。

3)        以p結尾的函數會搜尋PATH環境變數來尋找新程式,不存在則使用絕對路徑來傳遞給函數。

4)        exec函數不會返回調用它的函數。

2.        複製進程對象

#include <unistd.h>

#include<sys/types.h>

pid_t fork(void);

新進程與原進程一模一樣,執行代碼完全一樣,只是有自己的資料空間、環境以及檔案描述符。

傳回值:

-1:建立失敗;

0:當前進程為子進程;

非零:當前進程為父進程。

3.        進程等待

#include<sys/types.h>

#include<sys/wait.h>

pid_t wait(int*stat_loc);

pid_t waitpid(pid_t pid, int* stat_loc, int options);

int waitid(idtype_tidtype, id_t id, siginfo_t *infop, int options);

暫停父進程知道子進程結束為止。

stat_loc:

WIFEXITED

子進程正常結束,WIFEXITD(stat_loc)取非零值

WEXITSTATUS

WEXITSTATUS(stat_loc)非零時,為進程退出碼

WIFSIGNALED

如果子進程因一個為捕獲的訊號終止,WIFSIGNALED(stat_loc)非零

WTERMSIG

WTERMSIG(stat_loc)非零,則為訊號代碼

WCOREDUMP

子進程意外終止,WCOREDUMP(stat_loc)取非零

WIFSTOPPED

WIFSTOPPED(stat_loc)非零,則為一個訊號代碼

 

4.        exit

退出進程。 進程通訊、訊號

Linux 提供的大多數訊號類型是供核心使用的,只有少數的幾種訊號可以用作在進程之間傳送。下面給出常用的訊號和它們的意義:

SIGHUP

當終止一個終端時,核心就把這一種訊號發送給該終端所控制的所有進程。通常情況

下,一個進程組的控制終端是該使用者擁有的終端,但不完全是如此。當進程組的首進程結

束時,就會向該進程組的所有進程發送這種訊號。這就可以保證當一個使用者退出使用時,

其後台進程被終止,除非有其它方面的安排。

SIGINT

當一個使用者按了中斷鍵(一般為Ctrl+C)後,核心就向與該終端有關聯的所有進程發

送這種訊號。它提供了中止運行程式的簡便方法。

SIGQUIT

這種訊號與SIGINT 非常相似,當使用者按了退出鍵時(為ASCII 碼FS,通常為Ctrl+\),

核心就發送出這種訊號。SIGQUIT 將形成POSIX 標準所描述的非正常終止。我們稱這種

UNIX 實現的實際操作為核心轉貯(core dump),並用資訊“Quit (coredump)”指出這一操

作的發生。這時,該進程的映象被轉貯到一個磁碟檔案中,供調試之用。

SIGILL

當一個進程企圖執行一條非法指令時,核心就發出這種訊號。例如,在沒有相應硬體

支撐的條件下,企圖執行一條浮點指令時,則會引起這種訊號的發生。SIGILL 和SIGQUIT

一樣,也形成非正常終止。

SIGTRAP

這是一種由偵錯工具使用的專用訊號。由於他的專用行和特殊性,我們不再對它作進一步的討論。SIGTRAP 也形成非正常終止。

SIGFPE

當產生浮點錯誤時(比如溢出),核心就發出這種訊號,它導致非正常終止。

SIGKILL

這是一個相當特殊的訊號,它從一個進程發送到另一個進程,使接收到該訊號的進程

終止。核心偶爾也會發出這種訊號。SIGKILL 的特點是,它不能被忽略和捕捉,只能通過

使用者定義的相應中斷處理常式而處理該訊號。因為其它的所有訊號都能被忽略和捕捉,所

以只有這種訊號能絕對保證終止一個進程。

SIGALRM

當一個定時器到時的時候,核心就向進程發送這個訊號。定時器是由改進程自己用系

統調用alarm()設定的。

SIGTERM

這種訊號是由系統提供給普通程式使用的,按照規定,它被用來終止一個進程。

SIGSTOP

這個訊號使進程暫時中止運行,系統將控制權轉回正在等待啟動並執行下一個進程。

SIGUSR1 和SIGUSR2

和SIGTERM 一樣,這兩種訊號不是核心發送的,可以用於使用者所希望的任何目的。

SIGCHLD

子進程結束訊號。UNIX 中用它來實現系統調用exit()和wait()。執行exit()時,就向子進程的父進程發送SIGCHLD 訊號,如果這時父進程政在執行wait(),則它被喚醒;如果這時候父進程不是執行wait(),則此父進程不會捕捉SIGCHLD 訊號,因此該訊號不起作用,子進程進入過渡狀態(如果父進程忽略SIGCHLD,子進程就結束而不會進入過渡狀態)。這個機制對大多數UNIX 程式員來說是相當重要的。 訊號與處理

1.        發送訊號

#include <unistd.h>

unsigned  int alarm(unisigned int seconds);在seconds後發送一個SIGALRM訊號

intkill(pid_t pid, int sig);發送訊號到指定進程

2.        訊號處理

int signal(int sig, __sighandler_t handler);

sig: 指明了所要處理的訊號類型,它可以取除了SIGKILL 和SIGSTOP 外的任何一種訊號。

handler:可以取以下三種值:

1)       一個傳回值為整數的函數地址。

此函數必須在signal()被調用前聲明,handler 中為這個函數的名字。當接收到一個類型為sig 的訊號時,就執行handler 所指定的函數。這個函數應有如下形式的定義:

int func(int sig);

sig 是傳遞給它的唯一參數。執行了signal()調用後,進程只要接收到類型為sig 的訊號,

不管其正在執行程式的哪一部分,就立即執行func()函數。當func()函數執行結束後,控制

權返回進程被中斷的那一點繼續執行。

2)        SIG_IGN

這個符號表示忽略訊號。執行了相應的signal()調用好,進程會忽略類型為sig 的訊號。

3)       SIG_DFL

這個符號表示恢複系統對訊號的預設處理。 處理序間通訊(管道)

1.       #include <unistd.h>

Int pipe(intfd[2]);

功能:擷取兩個管道描述符;

傳回值:-1表示失敗,0表示成功。

2.       標準I/O函數中的管道

#include<stdio.h>

FILE *popen(constchar *cmdstring, const char *type);

int pclose(FILE*pf);

popen的功能:建立一個管道,然後調用fork產生一個子進程,調用exec執行cmdstring命令,關閉管道不使用短,執行shell以運行命令,然後等待命令終止。

參數:

cmdstring :需要執行的shell命令。

type:若為”r”,命令串連至標準輸出;若為”w”,命令串連至標準輸入。

3.         多線程

1.        建立一個線程的函數:

         #include<pthread.h>

         intpthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr,void *(*start_rtn)(void),void *restrict arg);

 

         傳回值:若是成功建立線程返回0,否則返回錯誤的編號

         參數:

                   pthread_t*restrict tidp 要建立的線程的線程id指標

                   constpthread_attr_t *restrict attr 建立線程時的線程屬性

                   void* (start_rtn)(void)傳回值是void類型的指標函數

                   void *restrictarg start_rtn的形參

 

                   一般可以這樣用:

                   pthread_create(&id2,NULL, (void*)myThread1, NULL);

2.        等待一個線程的結束:pthread_join()函數,以阻塞的方式等待thread指定的線程結束

                   #include<pthread.h>

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

                   傳回值:

                            0代表成功。 失敗,返回的則是錯誤號碼

                   參數:

                            thread:線程標識符,即線程ID,標識唯一線程。

                         retval:使用者定義的指標,用來儲存被等待線程的傳回值。

3.        退出線程

void pthread_exit(void *retval);

4.        取消線程

int pthread_cancel(pthread_t thread);

5.        system

         system()會調用fork()產生子進程,由子進程來調用/bin/sh-c string來執行參數string字串所代表的命令,此命>令執行完後隨即返回原調用的進程。在調用system()期間SIGCHLD 訊號會被暫時擱置,SIGINT和SIGQUIT 訊號則會被忽略。

         #i nclude<stdlib.h>

         int system(const char *string);

         傳回值:

         -1:出現錯誤  

       0:調用成功但是沒有出現子進程  

                >0:成功退出的子進程的id

         參數:

                   String:命令列 核心驅動程式

1.      核心驅動程式主要架構

         核心驅動的開始的函數必須有為:

                   module_init(function)載入,和module_exit(function)卸載核心。

         核心驅動的函數頭都被定義到linux/或者asm/中。

2.      module_init( x);

driver initialization entry point.

參數:

x      function tobe run at kernel boot time or module insertion

3.      module_exit( x);

driver exit entry point.

參數:

x: function to be runwhen driver is removed

4.      outb()   I/O 上寫入 8 位元據 ( 1 位元組 );

inb() 從I/O連接埠讀取一個位元組(即八位)

inw 從I/O連接埠讀取一個字(即兩個位元組,十六位)

outw() I/O 上寫入 16 位元據 ( 2 位元組 );

outl () I/O 上寫入 32 位元據 ( 4 位元組)。

void outb (unsigned char data, unsigned short port);

byte inb(word port);返回一個位元組;

void outw (unsigned short data, unsigned short port);

word inw(word port);返回兩個位元組;

void outl (unsigned long data, unsigned short port);

5.       每個裝置都對應一個結構體:

struct file_operations {

    struct module *owner;//指向擁有這個模組的指標,該成員用來在它的操作還在是使用的時候不允許卸載該模組。

//通常情況下簡單初始化為THIS_MODULE。

    loff_t (*llseek) (struct file *, loff_t,int); //該操作用來改變當前檔案的讀寫位置,並且將新位置作為傳回值。

    ssize_t (*read) (struct file *, char __user*, size_t, loff_t *);//該操作用來從裝置中擷取資料。

    ssize_t (*write) (struct file *, const char__user *, size_t, loff_t *);//該操作用來發送資料給裝置。

    ssize_t (*aio_read) (struct kiocb *, conststruct iovec *, unsigned long, loff_t); //該操作用來初始化一個非同步讀操作。

    ssize_t (*aio_write) (struct kiocb *, conststruct iovec *, unsigned long, loff_t);//該操作用來初始化一個非同步寫操作。

    int (*readdir) (struct file *, void *,filldir_t);//該操作用來讀取目錄。

    unsigned int (*poll) (struct file *, structpoll_table_struct *);//該操作用來查詢一個或者多個檔案描述符的讀或寫是會否堵塞。

    int (*ioctl) (struct inode *, struct file*, unsigned int, unsigned long);//該操作用來提供發出裝置特定命令的方法。

    long(*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

    long (*compat_ioctl) (struct file *,unsigned int, unsigned long);

    int (*mmap) (struct file *, structvm_area_struct *);//該操作用來請求將裝置記憶體映射到進程的地址空間。

    int (*open) (struct inode *, struct file*);//該操作用來開啟裝置檔案,也是對裝置進行的第一個操作。

    int (*flush) (struct file *, fl_owner_tid);

    int (*release) (struct inode *, struct file*);//該操作用來釋放檔案結構。可以為空白。

    int (*fsync) (struct file *, struct dentry*, int datasync);

    int (*aio_fsync) (struct kiocb *, intdatasync);

    int (*fasync) (int, struct file *, int);

    int (*lock) (struct file *, int, structfile_lock *);

    ssize_t (*sendpage) (struct file *, structpage *, int, size_t, loff_t *, int);

    unsigned long (*get_unmapped_area)(structfile *, unsigned long, unsigned long, unsigned long, unsigned long);

    int (*check_flags)(int);

    int (*dir_notify)(struct file *filp,unsigned long arg);

    int (*flock) (struct file *, int, structfile_lock *);

    ssize_t (*splice_write)(structpipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);

    ssize_t (*splice_read)(struct file *,loff_t *, struct pipe_inode_info *, size_t, unsigned int);

    int (*setlease)(struct file *, long, structfile_lock **);

    int (*fsetattr)(struct file *, struct iattr*);

};

6.      將核心資料複製到使用者空間中

unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)

{

if (access_ok(VERIFY_WRITE, to, n))

n = __copy_to_user(to, from, n);

return n;

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.