cũng như đa số mọi người khi bắt đầu chuyển từ sử dụng windows sang linux(cụ thể ubuntu, asch, mint, centos...) sẽ gặp rất nhiều bỡ ngỡ, ngỡ mình cũng vậy vô số câu hỏi thắc mắc xung quanh nền tảng này: tại sao các ông lại dùng lệnh để gõ, tại sao không thao tác bằng giao diện đồ họa cho tiện, tại sao không chia thành các ổ địa như windows, tại sao tôi không có microsoft office, cùi bắp vậy shell là cái gì, kernel là cái gì
+linux là gì nó đến từ đâu và do ai tạo ra
+những thành phần chính cấu tạo nên 1 hệ thống linux
+chức năng nhiệm vụ tổng quan của những thành phần đó

linux là gì

khái niệm như LiveCD, GNU.. khi lựa chọn 1 phiên bản linux mà mình muốn sử dụng
-1 hệ thống linux có thể chia thành 4 thành phần chính
+linux kernel
+GNU utilities
+môi trường đồ họa desktop
+phần mềm ứng dụng
-linux kernel
lõi có thể hiểu là nhân(là xương sống, là tủy), kernel điều khiển toàn bộ hệ thống phần cứng cũng như phần mềm của hệ thống máy tính, có thể coi như là tướng quân điều binh khiển tướng
+chắc các bạn đã từng nghe đến linus cha đẻ cưa linux
+kernel đảm nhiệm 4 nhiệm vụ sau
quản lý bộ nhớ hệ thống, quản lý chương trình phần mềm, quản lý phần cứng, quản lý hệ thống lưu trữ
-GNU utilities 
bên cạnh việc cần có 1 lõi kernel kiểm soát các thiết bị phần cứng, 1 hệ điều hành máy tính cần có các tiện ích, các công cụ thực hiện các chức năng cơ bản, vì vậy kernel không tự thực hiện được các chức năng nó cần người ta ra lệnh
-những gói cung cụ chính của GNU có thể chia thành 3 nhóm
+công cụ xử lý files
+công cụ thao tác với văn bản
+công cụ quản lý các tiến trình
mỗi nhóm các công cụ này lại có thể có vô vàn các tiện ích khác nhau chúng có thể coi là vô giá đối với những ADmin hệ thống linux hay lập trình viên
shell
là 1 tool đặc biệt của GNU, nó cung cấp cho người dùng khả năng khởi chạy 1 chương trình, quản lý tài nguyên và quản lý tiến trình trên linux, thành phần cốt lõi của shell là command prompt(là thành phần có nhiệm vụ tương tác với shell). hay nói 1 cách dễ hiểu shell chính là command line interface(CLI) mà các bạn hay sử dụng nó như là terminal trên ubuntu
the linux desktop environment
vào thời kì sơ khai của linux mọi thao tác đều được thực hiện qua việc nhập text đơn giản, ADmin quản lý hệ thống điều khiển mọi thứ qua giao diện này, song song với linux là sự phát triển mạnh mẽ của windows cùng giao diện bắt mắt, thân thiện, người dùng linux đã mong đợi nhiều hơn, không chỉ là giao diện nhập lệnh trắng đen này nữa, chính điều này đã thôi thúc trong cộng đồng mã nguồn mở và giao diện đồ họa desktop cho linux ra đời
+linux nổi tiếng bởi tính mở của nó, bạn có thể làm được cùng 1 việc với nhiều cách khác nhau, giao diện đồ họa cũng vậy, cộng đồng lớn của linux đã phát triển ra vô vàn những giao diện đồ họa để phù hợp với các phiên bản của linux
  • X Window system
  • KDE Desktop
  • GNOME Desktop
  • Unity Desktop
Trong đó có thể kể đến GNOME và Unity là những cái tên vô cùng phổ biến, chính là giao diện mà mọi người sử dụng trên ubuntu các phiên bản gần đây.
 

-một trong những đặc điểm nổi bật của linux là chạy đồng thời nhiều chương trình. hệ điều hành coi đơn thể mã lệnh mà nó điều khiển là 1 tiến trình(PROCESS). một chương trình có thể gồm nhiều tiến trình phối hợp với nhau.
-đối với hệ điều hành, các tiến trình cùng hoạt động chia sẻ tốc độ xử lý của CPU, cùng dùng chung vùng nhớ và các tài nguyên hệ thống khác, các tiến trình được điều phối xoay vòng bởi hệ điều hành. nếu 1 chương trình của chúng ta mở dần ra, sẽ có lúc phải tách ra nhiều tiến trình để xử lý những công việc độc lập với nhau, các lệnh của linux là những lệnh riêng lẻ có khả năng kết hợp và truyền dữ liệu cho nhau thông qua các cơ chế như: đường ống pipe, chuyển hướng nhập xuất(redirect), phát sinh tín hiệu(signal).. chúng được gọi là cơ chế giao tiếp liên tiến trình(IPC inter process comunication) , đối với tiến trình chúng ta tìm hiểu cách tạo, hủy và tạm dừng tiến trình, đồng bộ hóa tiến trình và giao tiếp giữa các tiến trình với nhau
-xây dựng tiến trình trong môi trường đa tiến trình như trong linux là công việc khó khăn, không như trong môi trường đơn nhiệm trong môi trường đa nhiệm tiến trình có tài nguyên rất hạn hẹp, tiến trình của chúng ta khi hoạt động phải luôn ở trạng thái tôn trọng sẵn sàng nhường CPU cho tiến trình khác ở bất kỳ thời điểm nào khi hệ thống yêu cầu. nếu tiến trình của chúng ta được xây dựng không tốt, khi đổ vỡ và gây ra lỗi, nó có thể làm treo các tiến trình khác trong hệ thống hay phá vỡ cả hệ điều hành
-định nghĩa tiến trình:là thực thể điều khiển đoạn mã lệnh có riêng 1 không gian địa chỉ, có ngăn xếp stack riêng rẽ, có bảng chứa thông số mô tả file được mở cùng tiến trình và đặc biệt có 1 định danh PID(process Identify) duy nhất trong hệ thống trong thời điểm tiến trình đang chạy, như chúng ta thấy tiến trình không phải 1 chương trình(đôi lúc 1 chương trình đơn giản chỉ cần 1 tiến trình để hoàn thành tác vụ trong trường hợp này thì chúng ta có thể xem tiến trình và chương trình là 1). rất nhiều tiến trình có thể thực thi trên cùng 1 máy cùng 1 hệ điều hành cùng 1 người dùng hoặc nhiều người dùng đăng nhập. trong linux tiến trình được cấp không gian bộ nhớ phẳng là 4 GB, dữ liệu của tiến trình này không thể đọc và truy xuất bởi tiến trình khác, hai tiến trình khác nhau không thể xâm phạm biến của nhau, tuy nhiên  nếu chúng ta muốn chia sẽ dữ liệu giữa hai tiến trình, linux có thể cung cấp cho chúng ta 1 vùng không gian địa chỉ chung để làm điều này
cách hoạt động của tiến trình
khi 1 chương trình đang chạy từ dòng lệnh, chúng ta có thể nhấn ctrZ để tạm dừng chương trình và đưa nó hoạt động sau hậu trường(background). tiến trình của LINUX có các trạng thái
-đang chạy(running) đây là lúc tiến trình chiếm CPU dùng tính toán hay thực thi các công việc của mình
-chờ (waiting)tiến trình bị hệ điều hành tước quyền xử lý CPU, và chờ đến lượt cấp phát
-tạm dừng(suspend):hệ điều hành tạm dừng tiến trình, tiến trình được đưa vào trạng thái ngủ(sleep) khi cần thiết và có nhu cầu, hệ điều hành sẽ đánh thức(wake up) hay nạp lại mã lệnh của tiến trình vào bộ nhớ, cấp phát tài nguyên CPU để tiến trình tiếp tục hoạt động
bảng thông tin tiến trình
- hệ điều hành lưu giữ 1 cấu trúc bên trong hệ thống gọi là bảng tiến trình(process table). bảng tiến trình quản lý tất cả các PID của hệ thống và các thông tin chi tiết về tiến trình đang chạy
-tạo lập tiến trình
+gọi tiến trình mới bằng hàm system()
chúng ta có thể gọi 1 tiến trình khác bên trong 1 tiến trình đang thực thi bằng hàm system()
#include
int system(const char(cmdstr))
hàm này gọi chuỗi lệnh cmdstr thực thi và chờ lệnh cmdstr kết thúc mới quay về lời gọi hàm nó tương đương với việc bạn gọi shell thực thi lệnh của hệ thống
$sh –c cmdstr
thay tiến trình hiện hành với  các hàm exec
-mỗi tiến trình được hệ điều hành cung cấp 1 không gian nhớ tách biệt để tiến trình tự do hoạt động, nếu tiến trình A của ta gọi 1 chương trình ngoài B, hệ điều hành thường thực hiện các thao tác như, cấp phát không gian bộ nhớ cho tiến trình mới, điều chỉnh lại danh sách tiến trình nạp mã lệnh của chương trình B lên đĩa cứng và không gian nhớ vừa được cấp phát cho tiến trình, đưa tiến trình mới vào danh sách điều phối của hệ điều hành
-nếu tiến trình A đang chạy và nếu chúng ta muốn tiến trình B khởi chạy trong không gian bộ nhớ đã có sẵn của tiến trình A thì chúng ta có thể sử dụng hàm exec được cung cấp bởi linux
Các hàm exec sẽ thay thế toàn bộ ảnh của tiến trình A (bao gồm mã lệnh, dữ liệu, bảng mô tả file) thành ảnh của một tiến trình B hoàn toàn khác. Chỉ có số định danh PID của tiến trình A là còn giữ lại. Tập hàm exec bao gồm các hàm sau
nhân bản tiến trình với hàm fork()
thay thế tiến trình đôi khi bất lợi cho ta, đó là tiến trình mới chiếm hết không gian của tiến trình cũ, chúng ta không có khả năng kiểm soát tiến trình hiện hành sau khi gọi hàm exec nữa. cách đơn giản của linux là sử dụng hàm fork để nhân bản hay tạo bản sao mới của tiến trình, đặc biệt khi thực thi nó trả về 2 giá trị khác nhau trong lần thực thi
#include  #include  pid_t fork()
- Nếu thành công, fork() sẽ tách tiến trình hiện hành 2 tiến trình (dĩ nhiên Hệ Điều Hành phải cấp phát thêm không gian bộ nhớ để tiến trình mới hoạt động). Tiến trình ban đầu gọi là tiến trình cha (parent process) trong khi tiến trình mới gọi là tiến trình con (child process). Tiến trình con sẽ có một số định danh PID riêng biệt. ngoài ra, tiến trình con còn mang thêm một định danh PPID là số định danh PID của tiến trình cha
- Sau khi tách tiến trình, mã lệnh thực thi ở cả hai tiến trình được sao chép là hoàn toàn giống nhau. Chỉ có một dấu hiệu để chúng ta có thể nhận dạng tiến trình cha và tiến trình con, đó là trị trả về của hàm fork(). Bên trong tiến trình con, hàm fork() sẽ trả về trị 0. Trong khi bên trong tiến trình cha, hàm fork() sẽ trả về trị số nguyên chỉ là PID của tiến trình con vừa tạo. Trường hợp không tách được tiến trình, fork() sẽ trả về trị -1. Kiểu pid_t được khai báo và định nghĩa trong uinstd.h là kiểu số nguyên (int).
kiểm soát và đợi tiến trình con
khi fork() tách tiến trình thành 2 tiến trình cha và con, trên thực tế tiến trình cha và tiến trình con đều hoạt động độc lập, đôi lúc tiến trình cha cần tiến trình con thực hiện xong tác vụ mới tiếp tục thực thi
Ở ví dụ trên, khi thực thi, chúng ta sẽ thấy rằng tiến trình cha đã kết thúc mà tiến trình con vẫn in thông báo và cả tiến trình cha và tiến trình con đều tranh nhau gởi kết quả ra màn hình. Chúng ta không muốn điều này, chúng ta muốn rằng khi tiến trình cha kết thúc thì tiến trình con cũng hoàn tất thao tác của nó. Hơn nữa, chương trình con cần thực hiện xong tác vụ của nó thì mới đến chương trình cha. Để làm được việc này, chúng ta hãy sử dụng hàm wait()
Hàm wait khi được gọi sẽ yêu cầu tiến trình cha dừng lại chờ tiến trình con kết thúc trước khi thực hiện tiếp các lệnh điều khiển trong tiến trình cha. wait() làm cho sự liên hệ giữa tiến trình cha và tiến trình con trở nên tuần tự. Khi tiến trình con kết thúc, hàm sẽ trả về số PID tương ứng của tiến trình con. Nếu chúng ta truyền thêm đối số stat_loc khác NULL cho hàm thì wait() cũng sẽ trả về trạng thái mà tiến trình con kết thúc trong biến stat_loc. Chúng ta có thể sử dụng các macro khai báo sẵn trong sys/wait.h như sau: WIFEXITED (stat_loc) Trả về trị khác 0 nếu tiến trình con kết thúc bình thường. WEXITSTATUS (stat_loc) Nếu WIFEXITED trả về trị khác 0, macro này sẽ trả về mã lỗi của tiến trình con. WIFSIGNALED (stat_loc) Trả về trị khác 0 nếu tiến trình con kết thúc bởi một tín hiệu gửi đến. WTERMSIG(stat_loc) Nếu WIFSIGNALED khác 0, macro này sẽ cho biết số tín hiệu đã hủy tiến trình con. WIFSTOPPED(stat_loc) Trả về trị khác 0 nếu tiến trình con đã dừng. WSTOPSIG(stat_loc) Nếu WIFSTOPPED trả về trị khác 0, macro này trả về số hiệu của signa